diff options
author | Nick Clifton <nickc@redhat.com> | 2015-11-24 08:47:59 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2015-11-24 08:47:59 +0000 |
commit | 2e8cf49e1387eba9c4ce062885b99a6eb76c01f8 (patch) | |
tree | 363800e2edad589cb37f72e10fc842097a8ec9c4 /sim/aarch64 | |
parent | 351e610191016136a49ee2a0889f1c4929169fc6 (diff) | |
download | fsf-binutils-gdb-2e8cf49e1387eba9c4ce062885b99a6eb76c01f8.zip fsf-binutils-gdb-2e8cf49e1387eba9c4ce062885b99a6eb76c01f8.tar.gz fsf-binutils-gdb-2e8cf49e1387eba9c4ce062885b99a6eb76c01f8.tar.bz2 |
Add an AArch64 simulator to GDB.
sim * configure.tgt: Add aarch64 entry.
* configure: Regenerate.
* sim/aarch64/configure.ac: New configure template.
* sim/aarch64/aclocal.m4: Generate.
* sim/aarch64/config.in: Generate.
* sim/aarch64/configure: Generate.
* sim/aarch64/cpustate.c: New file - functions for accessing
AArch64 registers.
* sim/aarch64/cpustate.h: New header.
* sim/aarch64/decode.h: New header.
* sim/aarch64/interp.c: New file - interface between GDB and
simulator.
* sim/aarch64/Makefile.in: New makefile template.
* sim/aarch64/memory.c: New file - functions for simulating
aarch64 memory accesses.
* sim/aarch64/memory.h: New header.
* sim/aarch64/sim-main.h: New header.
* sim/aarch64/simulator.c: New file - aarch64 simulator
functions.
* sim/aarch64/simulator.h: New header.
include/gdb * sim-aarch64.h: New file.
sim/test * configure: Regenerate.
* sim/aarch64: New directory.
Diffstat (limited to 'sim/aarch64')
-rw-r--r-- | sim/aarch64/Makefile.in | 36 | ||||
-rw-r--r-- | sim/aarch64/aclocal.m4 | 110 | ||||
-rw-r--r-- | sim/aarch64/config.in | 160 | ||||
-rwxr-xr-x | sim/aarch64/configure | 15689 | ||||
-rw-r--r-- | sim/aarch64/configure.ac | 39 | ||||
-rw-r--r-- | sim/aarch64/cpustate.c | 557 | ||||
-rw-r--r-- | sim/aarch64/cpustate.h | 333 | ||||
-rw-r--r-- | sim/aarch64/decode.h | 418 | ||||
-rw-r--r-- | sim/aarch64/interp.c | 483 | ||||
-rw-r--r-- | sim/aarch64/memory.c | 196 | ||||
-rw-r--r-- | sim/aarch64/memory.h | 64 | ||||
-rw-r--r-- | sim/aarch64/sim-main.h | 68 | ||||
-rw-r--r-- | sim/aarch64/simulator.c | 13047 | ||||
-rw-r--r-- | sim/aarch64/simulator.h | 57 |
14 files changed, 31257 insertions, 0 deletions
diff --git a/sim/aarch64/Makefile.in b/sim/aarch64/Makefile.in new file mode 100644 index 0000000..c07a868 --- /dev/null +++ b/sim/aarch64/Makefile.in @@ -0,0 +1,36 @@ +#### Makefile.in --- Makefile template for the AArch64 simulator + +### Copyright (C) 2015 Free Software Foundation, Inc. + +### Contributed by Red Hat. + +### This file is part of GDB. + +### 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; either version 3 of the License, or +### (at your option) any later version. +### +### 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, see <http://www.gnu.org/licenses/>. */ + +## COMMON_PRE_CONFIG_FRAG + +SIM_EXTRA_LIBS = -lm + +SIM_OBJS = \ + $(SIM_NEW_COMMON_OBJS) \ + interp.o \ + cpustate.o \ + simulator.o \ + memory.o \ + sim-hload.o \ + sim-resume.o \ + +## COMMON_POST_CONFIG_FRAG + diff --git a/sim/aarch64/aclocal.m4 b/sim/aarch64/aclocal.m4 new file mode 100644 index 0000000..995d7f9 --- /dev/null +++ b/sim/aarch64/aclocal.m4 @@ -0,0 +1,110 @@ +# generated automatically by aclocal 1.11.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008, +# 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless `enable' is passed literally. +# For symmetry, `disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], +[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +m4_include([../../config/lead-dot.m4]) diff --git a/sim/aarch64/config.in b/sim/aarch64/config.in new file mode 100644 index 0000000..3152bea --- /dev/null +++ b/sim/aarch64/config.in @@ -0,0 +1,160 @@ +/* config.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the <errno.h> header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the <fpu_control.h> header file. */ +#undef HAVE_FPU_CONTROL_H + +/* Define to 1 if you have the `getrusage' function. */ +#undef HAVE_GETRUSAGE + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <sys/resource.h> header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the `time' function. */ +#undef HAVE_TIME + +/* Define to 1 if you have the <time.h> header file. */ +#undef HAVE_TIME_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the <windows.h> header file. */ +#undef HAVE_WINDOWS_H + +/* Define to 1 if you have the `__setfpucw' function. */ +#undef HAVE___SETFPUCW + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Name of this package. */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Additional package description */ +#undef PKGVERSION + +/* Bug reporting address */ +#undef REPORT_BUGS_TO + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE + +#include "tconfig.h" diff --git a/sim/aarch64/configure b/sim/aarch64/configure new file mode 100755 index 0000000..5f078bf --- /dev/null +++ b/sim/aarch64/configure @@ -0,0 +1,15689 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.64. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software +# Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +exec 7<&0 </dev/null 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="Makefile.in" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +cgen_breaks +REPORT_BUGS_TEXI +REPORT_BUGS_TO +PKGVERSION +sim_profile +sim_trace +sim_stdio +sim_debug +sim_cflags +sim_bswap +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +lt_cv_dlopen_libs +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +AWK +STRIP +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +LIBTOOL +PLUGINS_FALSE +PLUGINS_TRUE +zlibinc +zlibdir +CATOBJEXT +GENCAT +INSTOBJEXT +DATADIRNAME +CATALOGS +POSUB +GMSGFMT +XGETTEXT +INCINTL +LIBINTL_DEP +LIBINTL +USE_NLS +GMAKE_FALSE +GMAKE_TRUE +MAKE +CCDEPMODE +DEPDIR +am__leading_dot +PACKAGE +RANLIB +AR +HDEFINES +CC_FOR_BUILD +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +EGREP +GREP +CPP +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +WERROR_CFLAGS +WARN_CFLAGS +sim_xor_endian +sim_stdcall +sim_smp +sim_reserved_bits +sim_regparm +sim_packages +sim_inline +sim_hw +sim_hw_objs +sim_hw_cflags +sim_default_model +sim_scache +sim_float +sim_hostendian +sim_endian +sim_bitsize +sim_assert +sim_alignment +sim_environment +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_system_zlib +enable_plugins +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +enable_libtool_lock +enable_maintainer_mode +enable_sim_bswap +enable_sim_cflags +enable_sim_debug +enable_sim_stdio +enable_sim_trace +enable_sim_profile +with_pkgversion +with_bugurl +enable_sim_endian +enable_sim_alignment +enable_sim_hostendian +enable_sim_environment +enable_sim_inline +enable_werror +enable_build_warnings +enable_sim_build_warnings +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information." + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-plugins Enable support for plugins + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + --enable-sim-bswap Use Host specific BSWAP instruction + --enable-sim-cflags=opts + Extra CFLAGS for use in building simulator + --enable-sim-debug=opts Enable debugging flags (for developers of the sim + itself) + --enable-sim-stdio Specify whether to use stdio for console + input/output + --enable-sim-trace=opts Enable tracing of simulated programs + --enable-sim-profile=opts + Enable profiling flags + --enable-sim-endian=endian + Specify target byte endian orientation + --enable-sim-alignment=align + Specify strict, nonstrict or forced alignment of + memory accesses + --enable-sim-hostendian=end + Specify host byte endian orientation + --enable-sim-environment=environment + Specify mixed, user, virtual or operating + environment + --enable-sim-inline=inlines + Specify which functions should be inlined + --enable-werror treat compile warnings as errors + --enable-build-warnings enable build-time compiler warnings if gcc is used + --enable-sim-build-warnings + enable SIM specific build-time compiler warnings if + gcc is used + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-system-zlib use installed libz + --with-pic try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-pkgversion=PKG Use PKG in the version string in place of "SIM" + --with-bugurl=URL Direct users to URL to report a bug + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.64 + +Copyright (C) 2009 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + return $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + return $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + return $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + return $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.64. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + ac_site_file1=$CONFIG_SITE +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# This file contains common code used by all simulators. +# +# SIM_AC_COMMON invokes AC macros used by all simulators and by the common +# directory. It is intended to be invoked before any target specific stuff. +# SIM_AC_OUTPUT is a cover function to AC_OUTPUT to generate the Makefile. +# It is intended to be invoked last. +# +# The simulator's configure.ac should look like: +# +# dnl Process this file with autoconf to produce a configure script. +# AC_PREREQ(2.64)dnl +# AC_INIT(Makefile.in) +# sinclude(../common/aclocal.m4) +# +# SIM_AC_COMMON +# +# ... target specific stuff ... +# +# SIM_AC_OUTPUT + +# Include global overrides and fixes for Autoconf. + + + + + + + + + + + + + + + + + + + + + + + + + + +# _AC_CHECK_DECL_BODY +# ------------------- +# Shell function body for AC_CHECK_DECL. +# _AC_CHECK_DECL_BODY + +# _AC_CHECK_DECLS(SYMBOL, ACTION-IF_FOUND, ACTION-IF-NOT-FOUND, +# INCLUDES) +# ------------------------------------------------------------- +# Helper to AC_CHECK_DECLS, which generates the check for a single +# SYMBOL with INCLUDES, performs the AC_DEFINE, then expands +# ACTION-IF-FOUND or ACTION-IF-NOT-FOUND. + + + + + + + + + + + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + + + +# serial 56 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. + + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters + + + +# LT_INIT([OPTIONS]) +# ------------------ +# LT_INIT + +# Old names: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. + + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. + + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. + + +# Initialize. + + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. + + +# Initialize. + + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- + + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. + + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. + + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- + + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ + + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- + + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- + + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- + + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- + + + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ + + + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. + + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`' + + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script + + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name + + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. + + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- + + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ + + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +#_LT_CONFIG_COMMANDS + + +# Initialize. + + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' + + + +# C support is built-in for now + + + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +# _LT_LANG + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# _LT_TAG_COMPILER +# ---------------- +# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- + + + +# _LT_DARWIN_LINKER_FEATURES +# -------------------------- +# Checks for linker and compiler features on darwin + + +# _LT_SYS_MODULE_PATH_AIX +# ----------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +# _LT_PROG_ECHO_BACKSLASH + + +# _LT_ENABLE_LOCK +# --------------- +# _LT_ENABLE_LOCK + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +# _LT_COMPILER_OPTION + +# Old name: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +# _LT_LINKER_OPTION + +# Old name: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# LT_CMD_MAX_LEN +#--------------- +# LT_CMD_MAX_LEN + +# Old name: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# _LT_HEADER_DLFCN +# ---------------- +# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +# LT_SYS_DLOPEN_SELF + +# Old name: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +# _LT_PATH_TOOL_PREFIX + +# Old name: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +# LT_PATH_LD + +# Old names: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# _LT_PATH_LD_GNU +#- -------------- +# _LT_PATH_LD_GNU + + +# _LT_CMD_RELOAD +# -------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +# _LT_CMD_RELOAD + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +# LT_PATH_NM + +# Old names: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# LT_LIB_M +# -------- +# check for math library +# LT_LIB_M + +# Old name: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- + # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +# _LT_LANG_CXX_CONFIG + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- + + +# Old name: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# LT_PROG_RC +# ---------- + + +# Old name: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. + + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. + + + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +# _LT_DECL_SED + +#m4_ifndef + +# Old name: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_XSI_SHELLFNS +# --------------------- +# Bourne and XSI compatible variants of some useful shell functions. + + +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. + + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ + + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. + + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. + + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. + + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- + + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +# LT_OPTION_DEFINE + + +# dlopen +# ------ + + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +# win32-dll + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# _LT_ENABLE_SHARED + + + + +# Old names: + + + + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# _LT_ENABLE_STATIC + + + + +# Old names: + + + + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# _LT_ENABLE_FAST_INSTALL + + + + +# Old names: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +# _LT_WITH_PIC + + + + +# Old name: +# This is what autoupdate's m4 run will expand. It fires +# the warning (with _au_warn_XXX), outputs it into the +# updated configure.ac (with AC_DIAGNOSE), and then outputs +# the replacement expansion. + + +# This is an auxiliary macro that is also run when +# autoupdate runs m4. It simply calls m4_warning, but +# we need a wrapper so that each warning is emitted only +# once. We break the quoting in m4_warning's argument in +# order to expand this macro's arguments, not AU_DEFUN's. + + +# Finally, this is the expansion that is picked up by +# autoconf. It tells the user to run autoupdate, and +# then outputs the replacement expansion. We do not care +# about autoupdate's warning because that contains +# information on what to do *after* running autoupdate. + + + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + + + + + + + + + + +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. + + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. + + + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. + + + + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. + + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. + + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. + + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- + + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- + + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- + + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- + + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- + + +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# Generated from ltversion.in. + +# serial 3134 ltversion.m4 +# This file is part of GNU Libtool + + + + + + +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 4 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# Based on depend.m4 from automake 1.9, modified for standalone use in +# an environment where GNU make is required. + +# ZW_PROG_COMPILER_DEPENDENCIES +# ----------------------------- +# Variant of _AM_DEPENDENCIES which just does the dependency probe and +# sets fooDEPMODE accordingly. Cache-variable compatible with +# original; not side-effect compatible. As the users of this macro +# may require accurate dependencies for correct builds, it does *not* +# honor --disable-dependency-checking, and failure to detect a usable +# method is an error. depcomp is assumed to be located in +# $ac_aux_dir. +# +# FIXME: Should use the Autoconf 2.5x language-selection mechanism. + + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. + + +# ZW_CREATE_DEPDIR +# ---------------- +# As AM_SET_DEPDIR, but also create the directory at config.status time. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +sim_inline="-DDEFAULT_INLINE=0" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# intl sister-directory configuration rules. +# + +# The idea behind this macro is that there's no need to repeat all the +# autoconf probes done by the intl directory - it's already done them +# for us. In fact, there's no need even to look at the cache for the +# answers. All we need to do is nab a few pieces of information. +# The intl directory is set up to make this easy, by generating a +# small file which can be sourced as a shell script; then we produce +# the necessary substitutions and definitions for this directory. + + + +# Autoconf M4 include file defining utility macros for complex Canadian +# cross builds. + + + + + + + + + +#### +# _NCN_TOOL_PREFIXES: Some stuff that oughtta be done in AC_CANONICAL_SYSTEM +# or AC_INIT. +# These demand that AC_CANONICAL_SYSTEM be called beforehand. + +#### +# NCN_STRICT_CHECK_TOOLS(variable, progs-to-check-for,[value-if-not-found],[path]) +# Like plain AC_CHECK_TOOLS, but require prefix if build!=host. + + +#### +# NCN_STRICT_CHECK_TARGET_TOOLS(variable, progs-to-check-for,[value-if-not-found],[path]) +# Like CVS Autoconf AC_CHECK_TARGET_TOOLS, but require prefix if build!=target. + + + +# Backported from Autoconf 2.5x; can go away when and if +# we switch. Put the OS path separator in $PATH_SEPARATOR. + + + + +# ACX_HAVE_GCC_FOR_TARGET +# Check if the variable GCC_FOR_TARGET really points to a GCC binary. + + +# ACX_CHECK_INSTALLED_TARGET_TOOL(VAR, PROG) +# Searching for installed target binutils. We need to take extra care, +# else we may find the wrong assembler, linker, etc., and lose. +# +# First try --with-build-time-tools, if specified. +# +# For build != host, we ask the installed GCC for the name of the tool it +# uses, and accept it if it is an absolute path. This is because the +# only good choice for a compiler is the same GCC version that is being +# installed (or we couldn't make target libraries), and we assume that +# on the host system we'll have not only the same GCC version, but also +# the same binutils version. +# +# For build == host, search the same directories that the installed +# compiler will search. We used to do this for the assembler, linker, +# and nm only; for simplicity of configuration, however, we extend this +# criterion to tools (such as ar and ranlib) that are never invoked by +# the compiler, to avoid mismatches. +# +# Also note we have to check MD_EXEC_PREFIX before checking the user's path +# if build == target. This makes the most sense only when bootstrapping, +# but we also do so when build != host. In this case, we hope that the +# build and host systems will have similar contents of MD_EXEC_PREFIX. +# +# If we do not find a suitable binary, then try the user's path. + + +### +# AC_PROG_CPP_WERROR +# Used for autoconf 2.5x to force AC_PREPROC_IFELSE to reject code which +# triggers warnings from the preprocessor. Will be in autoconf 2.58. +# For now, using this also overrides header checks to use only the +# preprocessor (matches 2.13 behavior; matching 2.58's behavior is a +# bit harder from here). +# Eventually autoconf will default to checking headers with the compiler +# instead, and we'll have to do this differently. + +# AC_PROG_CPP_WERROR + +# Test for GNAT. +# We require the gnatbind & gnatmake programs, as well as a compiler driver +# that understands Ada. We use the user's CC setting, already found, and +# possibly add $1 to the command-line parameters. +# +# Sets the shell variable have_gnat to yes or no as appropriate, and +# substitutes GNATBIND and GNATMAKE. + + + + + + + + + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "no acceptable C compiler found in \$PATH +See \`config.log' for more details." "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + rm -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +if test -z "$ac_file"; then : + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ as_fn_set_status 77 +as_fn_error "C compiler cannot create executables +See \`config.log' for more details." "$LINENO" 5; }; } +fi +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." "$LINENO" 5; } +fi +rm -f conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot compute suffix of object files: cannot compile +See \`config.log' for more details." "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + for ac_t in install-sh install.sh shtool; do + if test -f "$ac_dir/$ac_t"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/$ac_t -c" + break 2 + fi + done +done +if test -z "$ac_aux_dir"; then + as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if test "${ac_cv_build+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if test "${ac_cv_target+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if test "${ac_cv_path_GREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = x""yes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if test "${ac_cv_safe_to_define___extensions__+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +DEPDIR="${am__leading_dot}deps" + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.2.7a' +macro_revision='1.3134' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`print -r -- -n 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if test "${ac_cv_path_SED+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if test "${ac_cv_path_FGREP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test "${lt_cv_path_LD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if test "${lt_cv_prog_gnu_ld+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if test "${lt_cv_path_NM+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_DUMPBIN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if test "${lt_cv_nm_interface+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if test "${lt_cv_sys_max_cmd_len+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if test "${lt_cv_ld_reload_flag+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OBJDUMP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if test "${lt_cv_deplibs_check_method+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + + + + + + + + + + + + + + + + + + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if test "${lt_cv_cc_needs_belf+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_DSYMUTIL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_NMEDIT+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_LIPO+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OTOOL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_OTOOL64+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if test "${lt_cv_apple_cc_single_mod+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if test "${lt_cv_ld_exported_symbols_list+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if test "${lt_cv_ld_force_load+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + +# autoconf.info says this should be called right after AC_INIT. +ac_config_headers="$ac_config_headers config.h:config.in" + + + + + + +# Put a plausible default for CC_FOR_BUILD in Makefile. +if test "x$cross_compiling" = "xno"; then + CC_FOR_BUILD='$(CC)' +else + CC_FOR_BUILD=gcc +fi + + + + +AR=${AR-ar} + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + + + +# Some of the common include files depend on bfd.h, and bfd.h checks +# that config.h is included first by testing that the PACKAGE macro +# is defined. +PACKAGE=sim + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + + +# Dependency checking. +ac_config_commands="$ac_config_commands depdir" + + +depcc="$CC" am_compiler_list= + +am_depcomp=$ac_aux_dir/depcomp +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + if test $depmode = none; then break; fi + + $as_echo "$as_me:$LINENO: trying $depmode" >&5 + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "include sub/conftest.Po" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + depcmd="depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c" + echo "| $depcmd" | sed -e 's/ */ /g' >&5 + if env $depcmd > conftest.err 2>&1 && + grep sub/conftst6.h sub/conftest.Po >>conftest.err 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po >>conftest.err 2>&1 && + ${MAKE-make} -s -f confmf >>conftest.err 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + $as_echo "$as_me:$LINENO: success" >&5 + break + fi + fi + $as_echo "$as_me:$LINENO: failure, diagnostics are:" >&5 + sed -e 's/^/| /' < conftest.err >&5 + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +if test x${am_cv_CC_dependencies_compiler_type-none} = xnone +then as_fn_error "no usable dependency style found" "$LINENO" 5 +else CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + +fi + + +# Check for the 'make' the user wants to use. +for ac_prog in make +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_MAKE+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MAKE"; then + ac_cv_prog_MAKE="$MAKE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MAKE="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MAKE=$ac_cv_prog_MAKE +if test -n "$MAKE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE" >&5 +$as_echo "$MAKE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$MAKE" && break +done + +MAKE_IS_GNU= +case "`$MAKE --version 2>&1 | sed 1q`" in + *GNU*) + MAKE_IS_GNU=yes + ;; +esac + if test "$MAKE_IS_GNU" = yes; then + GMAKE_TRUE= + GMAKE_FALSE='#' +else + GMAKE_TRUE='#' + GMAKE_FALSE= +fi + + +ALL_LINGUAS= +# If we haven't got the data from the intl directory, +# assume NLS is disabled. +USE_NLS=no +LIBINTL= +LIBINTL_DEP= +INCINTL= +XGETTEXT= +GMSGFMT= +POSUB= + +if test -f ../../intl/config.intl; then + . ../../intl/config.intl +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 +$as_echo_n "checking whether NLS is requested... " >&6; } +if test x"$USE_NLS" != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define ENABLE_NLS 1" >>confdefs.h + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for catalogs to be installed" >&5 +$as_echo_n "checking for catalogs to be installed... " >&6; } + # Look for .po and .gmo files in the source directory. + CATALOGS= + XLINGUAS= + for cat in $srcdir/po/*.gmo $srcdir/po/*.po; do + # If there aren't any .gmo files the shell will give us the + # literal string "../path/to/srcdir/po/*.gmo" which has to be + # weeded out. + case "$cat" in *\**) + continue;; + esac + # The quadruple backslash is collapsed to a double backslash + # by the backticks, then collapsed again by the double quotes, + # leaving us with one backslash in the sed expression (right + # before the dot that mustn't act as a wildcard). + cat=`echo $cat | sed -e "s!$srcdir/po/!!" -e "s!\\\\.po!.gmo!"` + lang=`echo $cat | sed -e "s!\\\\.gmo!!"` + # The user is allowed to set LINGUAS to a list of languages to + # install catalogs for. If it's empty that means "all of them." + if test "x$LINGUAS" = x; then + CATALOGS="$CATALOGS $cat" + XLINGUAS="$XLINGUAS $lang" + else + case "$LINGUAS" in *$lang*) + CATALOGS="$CATALOGS $cat" + XLINGUAS="$XLINGUAS $lang" + ;; + esac + fi + done + LINGUAS="$XLINGUAS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINGUAS" >&5 +$as_echo "$LINGUAS" >&6; } + + + DATADIRNAME=share + + INSTOBJEXT=.mo + + GENCAT=gencat + + CATOBJEXT=.gmo + +fi + +# Check for common headers. +# FIXME: Seems to me this can cause problems for i386-windows hosts. +# At one point there were hardcoded AC_DEFINE's if ${host} = i386-*-windows*. +for ac_header in stdlib.h string.h strings.h unistd.h time.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in sys/time.h sys/resource.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in fcntl.h fpu_control.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in dlfcn.h errno.h sys/stat.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_func in getrusage time sigaction __setfpucw +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# Check for socket libraries +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for bind in -lsocket" >&5 +$as_echo_n "checking for bind in -lsocket... " >&6; } +if test "${ac_cv_lib_socket_bind+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char bind (); +int +main () +{ +return bind (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_bind=yes +else + ac_cv_lib_socket_bind=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_bind" >&5 +$as_echo "$ac_cv_lib_socket_bind" >&6; } +if test "x$ac_cv_lib_socket_bind" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 +$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_gethostbyname=yes +else + ac_cv_lib_nsl_gethostbyname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 +$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } +if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBNSL 1 +_ACEOF + + LIBS="-lnsl $LIBS" + +fi + + +# BFD conditionally uses zlib, so we must link it in if libbfd does, by +# using the same condition. + + # Use the system's zlib library. + zlibdir="-L\$(top_builddir)/../zlib" + zlibinc="-I\$(top_srcdir)/../zlib" + +# Check whether --with-system-zlib was given. +if test "${with_system_zlib+set}" = set; then : + withval=$with_system_zlib; if test x$with_system_zlib = xyes ; then + zlibdir= + zlibinc= + fi + +fi + + + + + +# BFD uses libdl when when plugins enabled. + + maybe_plugins=no + for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + maybe_plugins=yes +fi + +done + + for ac_header in windows.h +do : + ac_fn_c_check_header_compile "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default +" +if test "x$ac_cv_header_windows_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_WINDOWS_H 1 +_ACEOF + maybe_plugins=yes +fi + +done + + + # Check whether --enable-plugins was given. +if test "${enable_plugins+set}" = set; then : + enableval=$enable_plugins; case "${enableval}" in + no) plugins=no ;; + *) plugins=yes + if test "$maybe_plugins" != "yes" ; then + as_fn_error "Building with plugin support requires a host that supports dlopen." "$LINENO" 5 + fi ;; + esac +else + plugins=$maybe_plugins + +fi + + if test "$plugins" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 +$as_echo_n "checking for library containing dlopen... " >&6; } +if test "${ac_cv_search_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dlopen=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_dlopen+set}" = set; then : + break +fi +done +if test "${ac_cv_search_dlopen+set}" = set; then : + +else + ac_cv_search_dlopen=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 +$as_echo "$ac_cv_search_dlopen" >&6; } +ac_res=$ac_cv_search_dlopen +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + fi + + if test "$plugins" = yes; then + PLUGINS_TRUE= + PLUGINS_FALSE='#' +else + PLUGINS_TRUE='#' + PLUGINS_FALSE= +fi + + + + + +# Set options +enable_dlopen=yes + + + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; pic_mode="$withval" +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if test "${lt_cv_objdir+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + lt_prog_compiler_pic='-Xcompiler -fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 +$as_echo "$lt_prog_compiler_pic" >&6; } + + + + + + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test "${lt_cv_prog_compiler_pic_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test "${lt_cv_prog_compiler_static_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test "${lt_cv_prog_compiler_c_o+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec= + hardcode_libdir_flag_spec_ld='-rpath $libdir' + archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + enable_shared_with_static_runtimes=yes + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if test "${lt_cv_prog_compiler__b+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo(void) {} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if test "${lt_cv_archive_cmds_need_lc+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = x""yes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if test "${ac_cv_lib_dld_shl_load+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = x""yes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if test "${ac_cv_lib_dl_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if test "${ac_cv_lib_svld_dlopen+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = x""yes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if test "${ac_cv_lib_dld_dld_link+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = x""yes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if test "${lt_cv_dlopen_self+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 12320 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +void fnord () __attribute__((visibility("default"))); +#endif + +void fnord () { int i=42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if test "${lt_cv_dlopen_self_static+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line 12426 "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +void fnord () __attribute__((visibility("default"))); +#endif + +void fnord () { int i=42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + + +. ${srcdir}/../../bfd/configure.host + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + + +# Check whether --enable-sim-bswap was given. +if test "${enable_sim_bswap+set}" = set; then : + enableval=$enable_sim_bswap; case "${enableval}" in + yes) sim_bswap="-DWITH_BSWAP=1 -DUSE_BSWAP=1";; + no) sim_bswap="-DWITH_BSWAP=0";; + *) as_fn_error "\"--enable-sim-bswap does not take a value\"" "$LINENO" 5; sim_bswap="";; +esac +if test x"$silent" != x"yes" && test x"$sim_bswap" != x""; then + echo "Setting bswap flags = $sim_bswap" 6>&1 +fi +else + sim_bswap="" +fi + + + +# Check whether --enable-sim-cflags was given. +if test "${enable_sim_cflags+set}" = set; then : + enableval=$enable_sim_cflags; case "${enableval}" in + yes) sim_cflags="-O2 -fomit-frame-pointer";; + trace) as_fn_error "\"Please use --enable-sim-debug instead.\"" "$LINENO" 5; sim_cflags="";; + no) sim_cflags="";; + *) sim_cflags=`echo "${enableval}" | sed -e "s/,/ /g"`;; +esac +if test x"$silent" != x"yes" && test x"$sim_cflags" != x""; then + echo "Setting sim cflags = $sim_cflags" 6>&1 +fi +else + sim_cflags="" +fi + + + +# Check whether --enable-sim-debug was given. +if test "${enable_sim_debug+set}" = set; then : + enableval=$enable_sim_debug; case "${enableval}" in + yes) sim_debug="-DDEBUG=7 -DWITH_DEBUG=7";; + no) sim_debug="-DDEBUG=0 -DWITH_DEBUG=0";; + *) sim_debug="-DDEBUG='(${enableval})' -DWITH_DEBUG='(${enableval})'";; +esac +if test x"$silent" != x"yes" && test x"$sim_debug" != x""; then + echo "Setting sim debug = $sim_debug" 6>&1 +fi +else + sim_debug="" +fi + + + +# Check whether --enable-sim-stdio was given. +if test "${enable_sim_stdio+set}" = set; then : + enableval=$enable_sim_stdio; case "${enableval}" in + yes) sim_stdio="-DWITH_STDIO=DO_USE_STDIO";; + no) sim_stdio="-DWITH_STDIO=DONT_USE_STDIO";; + *) as_fn_error "\"Unknown value $enableval passed to --enable-sim-stdio\"" "$LINENO" 5; sim_stdio="";; +esac +if test x"$silent" != x"yes" && test x"$sim_stdio" != x""; then + echo "Setting stdio flags = $sim_stdio" 6>&1 +fi +else + sim_stdio="" +fi + + + +# Check whether --enable-sim-trace was given. +if test "${enable_sim_trace+set}" = set; then : + enableval=$enable_sim_trace; case "${enableval}" in + yes) sim_trace="-DWITH_TRACE=-1";; + no) sim_trace="-DWITH_TRACE=0";; + [-0-9]*) + sim_trace="-DWITH_TRACE='(${enableval})'";; + [[:lower:]]*) + sim_trace="" + for x in `echo "$enableval" | sed -e "s/,/ /g"`; do + if test x"$sim_trace" = x; then + sim_trace="-DWITH_TRACE='(TRACE_$x" + else + sim_trace="${sim_trace}|TRACE_$x" + fi + done + sim_trace="$sim_trace)'" ;; +esac +if test x"$silent" != x"yes" && test x"$sim_trace" != x""; then + echo "Setting sim trace = $sim_trace" 6>&1 +fi +else + sim_trace="" +fi + + + +# Check whether --enable-sim-profile was given. +if test "${enable_sim_profile+set}" = set; then : + enableval=$enable_sim_profile; case "${enableval}" in + yes) sim_profile="-DPROFILE=1 -DWITH_PROFILE=-1";; + no) sim_profile="-DPROFILE=0 -DWITH_PROFILE=0";; + [-0-9]*) + sim_profile="-DPROFILE='(${enableval})' -DWITH_PROFILE='(${enableval})'";; + [a-z]*) + sim_profile="" + for x in `echo "$enableval" | sed -e "s/,/ /g"`; do + if test x"$sim_profile" = x; then + sim_profile="-DWITH_PROFILE='(PROFILE_$x" + else + sim_profile="${sim_profile}|PROFILE_$x" + fi + done + sim_profile="$sim_profile)'" ;; +esac +if test x"$silent" != x"yes" && test x"$sim_profile" != x""; then + echo "Setting sim profile = $sim_profile" 6>&1 +fi +else + sim_profile="-DPROFILE=1 -DWITH_PROFILE=-1" +fi + + + + +# Check whether --with-pkgversion was given. +if test "${with_pkgversion+set}" = set; then : + withval=$with_pkgversion; case "$withval" in + yes) as_fn_error "package version not specified" "$LINENO" 5 ;; + no) PKGVERSION= ;; + *) PKGVERSION="($withval) " ;; + esac +else + PKGVERSION="(SIM) " + +fi + + + + + +# Check whether --with-bugurl was given. +if test "${with_bugurl+set}" = set; then : + withval=$with_bugurl; case "$withval" in + yes) as_fn_error "bug URL not specified" "$LINENO" 5 ;; + no) BUGURL= + ;; + *) BUGURL="$withval" + ;; + esac +else + BUGURL="http://www.gnu.org/software/gdb/bugs/" + +fi + + case ${BUGURL} in + "") + REPORT_BUGS_TO= + REPORT_BUGS_TEXI= + ;; + *) + REPORT_BUGS_TO="<$BUGURL>" + REPORT_BUGS_TEXI=@uref{`echo "$BUGURL" | sed 's/@/@@/g'`} + ;; + esac; + + + + +cat >>confdefs.h <<_ACEOF +#define PKGVERSION "$PKGVERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define REPORT_BUGS_TO "$REPORT_BUGS_TO" +_ACEOF + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 +$as_echo_n "checking return type of signal handlers... " >&6; } +if test "${ac_cv_type_signal+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <signal.h> + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_type_signal=int +else + ac_cv_type_signal=void +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 +$as_echo "$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + + + + +sim_link_files= +sim_link_links= + +# targ-vals.def points to the libc macro description file. +case "${target}" in +*-*-*) TARG_VALS_DEF=../common/nltvals.def ;; +esac +sim_link_files="${sim_link_files} ${TARG_VALS_DEF}" +sim_link_links="${sim_link_links} targ-vals.def" + + + + +wire_endian="" +default_endian="" +# Check whether --enable-sim-endian was given. +if test "${enable_sim_endian+set}" = set; then : + enableval=$enable_sim_endian; case "${enableval}" in + b*|B*) sim_endian="-DWITH_TARGET_BYTE_ORDER=BIG_ENDIAN";; + l*|L*) sim_endian="-DWITH_TARGET_BYTE_ORDER=LITTLE_ENDIAN";; + yes) if test x"$wire_endian" != x; then + sim_endian="-DWITH_TARGET_BYTE_ORDER=${wire_endian}" + else + if test x"$default_endian" != x; then + sim_endian="-DWITH_TARGET_BYTE_ORDER=${default_endian}" + else + echo "No hard-wired endian for target $target" 1>&6 + sim_endian="-DWITH_TARGET_BYTE_ORDER=0" + fi + fi;; + no) if test x"$default_endian" != x; then + sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${default_endian}" + else + if test x"$wire_endian" != x; then + sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${wire_endian}" + else + echo "No default endian for target $target" 1>&6 + sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=0" + fi + fi;; + *) as_fn_error "\"Unknown value $enableval for --enable-sim-endian\"" "$LINENO" 5; sim_endian="";; +esac +if test x"$silent" != x"yes" && test x"$sim_endian" != x""; then + echo "Setting endian flags = $sim_endian" 6>&1 +fi +else + if test x"$default_endian" != x; then + sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${default_endian}" +else + if test x"$wire_endian" != x; then + sim_endian="-DWITH_TARGET_BYTE_ORDER=${wire_endian}" + else + sim_endian= + fi +fi +fi + +## We use NONSTRICT_ALIGNMENT as the default because AArch64 only +## enforces 4-byte alignment, even for 8-byte reads/writes. The +## common core does not support this, so we opt for non-strict +## alignment instead. +wire_alignment="NONSTRICT_ALIGNMENT" +default_alignment="NONSTRICT_ALIGNMENT" + +# Check whether --enable-sim-alignment was given. +if test "${enable_sim_alignment+set}" = set; then : + enableval=$enable_sim_alignment; case "${enableval}" in + strict | STRICT) sim_alignment="-DWITH_ALIGNMENT=STRICT_ALIGNMENT";; + nonstrict | NONSTRICT) sim_alignment="-DWITH_ALIGNMENT=NONSTRICT_ALIGNMENT";; + forced | FORCED) sim_alignment="-DWITH_ALIGNMENT=FORCED_ALIGNMENT";; + yes) if test x"$wire_alignment" != x; then + sim_alignment="-DWITH_ALIGNMENT=${wire_alignment}" + else + if test x"$default_alignment" != x; then + sim_alignment="-DWITH_ALIGNMENT=${default_alignment}" + else + echo "No hard-wired alignment for target $target" 1>&6 + sim_alignment="-DWITH_ALIGNMENT=0" + fi + fi;; + no) if test x"$default_alignment" != x; then + sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${default_alignment}" + else + if test x"$wire_alignment" != x; then + sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${wire_alignment}" + else + echo "No default alignment for target $target" 1>&6 + sim_alignment="-DWITH_DEFAULT_ALIGNMENT=0" + fi + fi;; + *) as_fn_error "\"Unknown value $enableval passed to --enable-sim-alignment\"" "$LINENO" 5; sim_alignment="";; +esac +if test x"$silent" != x"yes" && test x"$sim_alignment" != x""; then + echo "Setting alignment flags = $sim_alignment" 6>&1 +fi +else + if test x"$default_alignment" != x; then + sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${default_alignment}" +else + if test x"$wire_alignment" != x; then + sim_alignment="-DWITH_ALIGNMENT=${wire_alignment}" + else + sim_alignment= + fi +fi +fi + + +# Check whether --enable-sim-hostendian was given. +if test "${enable_sim_hostendian+set}" = set; then : + enableval=$enable_sim_hostendian; case "${enableval}" in + no) sim_hostendian="-DWITH_HOST_BYTE_ORDER=0";; + b*|B*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN";; + l*|L*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN";; + *) as_fn_error "\"Unknown value $enableval for --enable-sim-hostendian\"" "$LINENO" 5; sim_hostendian="";; +esac +if test x"$silent" != x"yes" && test x"$sim_hostendian" != x""; then + echo "Setting hostendian flags = $sim_hostendian" 6>&1 +fi +else + +if test "x$cross_compiling" = "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if test "${ac_cv_c_bigendian+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + #include <sys/param.h> + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + #include <sys/param.h> + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + if test $ac_cv_c_bigendian = yes; then + sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN" + else + sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN" + fi +else + sim_hostendian="-DWITH_HOST_BYTE_ORDER=0" +fi +fi + + +# Check whether --enable-sim-environment was given. +if test "${enable_sim_environment+set}" = set; then : + enableval=$enable_sim_environment; case "${enableval}" in + all | ALL) sim_environment="-DWITH_ENVIRONMENT=ALL_ENVIRONMENT";; + user | USER) sim_environment="-DWITH_ENVIRONMENT=USER_ENVIRONMENT";; + virtual | VIRTUAL) sim_environment="-DWITH_ENVIRONMENT=VIRTUAL_ENVIRONMENT";; + operating | OPERATING) sim_environment="-DWITH_ENVIRONMENT=OPERATING_ENVIRONMENT";; + *) as_fn_error "\"Unknown value $enableval passed to --enable-sim-environment\"" "$LINENO" 5; + sim_environment="";; +esac +if test x"$silent" != x"yes" && test x"$sim_environment" != x""; then + echo "Setting sim environment = $sim_environment" 6>&1 +fi +else + sim_environment="-DWITH_ENVIRONMENT=ALL_ENVIRONMENT" +fi + + +default_sim_inline="" +# Check whether --enable-sim-inline was given. +if test "${enable_sim_inline+set}" = set; then : + enableval=$enable_sim_inline; sim_inline="" +case "$enableval" in + no) sim_inline="-DDEFAULT_INLINE=0";; + 0) sim_inline="-DDEFAULT_INLINE=0";; + yes | 2) sim_inline="-DDEFAULT_INLINE=ALL_C_INLINE";; + 1) sim_inline="-DDEFAULT_INLINE=INLINE_LOCALS";; + *) for x in `echo "$enableval" | sed -e "s/,/ /g"`; do + new_flag="" + case "$x" in + *_INLINE=*) new_flag="-D$x";; + *=*) new_flag=`echo "$x" | sed -e "s/=/_INLINE=/" -e "s/^/-D/"`;; + *_INLINE) new_flag="-D$x=ALL_C_INLINE";; + *) new_flag="-D$x""_INLINE=ALL_C_INLINE";; + esac + if test x"$sim_inline" = x""; then + sim_inline="$new_flag" + else + sim_inline="$sim_inline $new_flag" + fi + done;; +esac +if test x"$silent" != x"yes" && test x"$sim_inline" != x""; then + echo "Setting inline flags = $sim_inline" 6>&1 +fi +else + +if test "x$cross_compiling" = "xno"; then + if test x"$GCC" != "x" -a x"${default_sim_inline}" != "x" ; then + sim_inline="${default_sim_inline}" + if test x"$silent" != x"yes"; then + echo "Setting inline flags = $sim_inline" 6>&1 + fi + else + sim_inline="" + fi +else + sim_inline="-DDEFAULT_INLINE=0" +fi +fi + + +# Check whether --enable-werror was given. +if test "${enable_werror+set}" = set; then : + enableval=$enable_werror; case "${enableval}" in + yes | y) ERROR_ON_WARNING="yes" ;; + no | n) ERROR_ON_WARNING="no" ;; + *) as_fn_error "bad value ${enableval} for --enable-werror" "$LINENO" 5 ;; + esac +fi + + +# Enable -Werror by default when using gcc +if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" ; then + ERROR_ON_WARNING=yes +fi + +WERROR_CFLAGS="" +if test "${ERROR_ON_WARNING}" = yes ; then +# NOTE: Disabled in the sim dir due to most sims generating warnings. +# WERROR_CFLAGS="-Werror" + true +fi + +build_warnings="-Wall -Wdeclaration-after-statement -Wpointer-arith \ +-Wpointer-sign \ +-Wno-unused -Wunused-value -Wunused-function \ +-Wno-switch -Wno-char-subscripts -Wmissing-prototypes +-Wdeclaration-after-statement -Wempty-body -Wmissing-parameter-type \ +-Wold-style-declaration -Wold-style-definition" + +# Enable -Wno-format by default when using gcc on mingw since many +# GCC versions complain about %I64. +case "${host}" in + *-*-mingw32*) build_warnings="$build_warnings -Wno-format" ;; + *) build_warnings="$build_warnings -Wformat-nonliteral" ;; +esac + +# Check whether --enable-build-warnings was given. +if test "${enable_build_warnings+set}" = set; then : + enableval=$enable_build_warnings; case "${enableval}" in + yes) ;; + no) build_warnings="-w";; + ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${build_warnings} ${t}";; + *,) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${t} ${build_warnings}";; + *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;; +esac +if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then + echo "Setting compiler warning flags = $build_warnings" 6>&1 +fi +fi +# Check whether --enable-sim-build-warnings was given. +if test "${enable_sim_build_warnings+set}" = set; then : + enableval=$enable_sim_build_warnings; case "${enableval}" in + yes) ;; + no) build_warnings="-w";; + ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${build_warnings} ${t}";; + *,) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${t} ${build_warnings}";; + *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;; +esac +if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then + echo "Setting GDB specific compiler warning flags = $build_warnings" 6>&1 +fi +fi +WARN_CFLAGS="" +if test "x${build_warnings}" != x -a "x$GCC" = xyes +then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler warning flags" >&5 +$as_echo_n "checking compiler warning flags... " >&6; } + # Separate out the -Werror flag as some files just cannot be + # compiled with it enabled. + for w in ${build_warnings}; do + case $w in + -Werr*) WERROR_CFLAGS=-Werror ;; + *) # Check that GCC accepts it + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $w" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + WARN_CFLAGS="${WARN_CFLAGS} $w" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$saved_CFLAGS" + esac + done + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${WARN_CFLAGS} ${WERROR_CFLAGS}" >&5 +$as_echo "${WARN_CFLAGS} ${WERROR_CFLAGS}" >&6; } +fi + + + +ac_sources="$sim_link_files" +ac_dests="$sim_link_links" +while test -n "$ac_sources"; do + set $ac_dests; ac_dest=$1; shift; ac_dests=$* + set $ac_sources; ac_source=$1; shift; ac_sources=$* + ac_config_links_1="$ac_config_links_1 $ac_dest:$ac_source" +done +ac_config_links="$ac_config_links $ac_config_links_1" + +cgen_breaks="" +if grep CGEN_MAINT $srcdir/Makefile.in >/dev/null; then +cgen_breaks="break cgen_rtx_error"; +fi + +ac_config_files="$ac_config_files Makefile.sim:Makefile.in" + +ac_config_files="$ac_config_files Make-common.sim:../common/Make-common.in" + +ac_config_files="$ac_config_files .gdbinit:../common/gdbinit.in" + +ac_config_commands="$ac_config_commands Makefile" + +ac_config_commands="$ac_config_commands stamp-h" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${GMAKE_TRUE}" && test -z "${GMAKE_FALSE}"; then + as_fn_error "conditional \"GMAKE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${PLUGINS_TRUE}" && test -z "${PLUGINS_FALSE}"; then + as_fn_error "conditional \"PLUGINS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.64. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_links="$ac_config_links" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration links: +$config_links + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.64, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2009 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +ac_aux_dir=$ac_aux_dir DEPDIR=$DEPDIR + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +AR \ +AR_FLAGS \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_wl \ +lt_prog_compiler_pic \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_flag_spec_ld \ +hardcode_libdir_separator \ +fix_srcfile_path \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;; + "depdir") CONFIG_COMMANDS="$CONFIG_COMMANDS depdir" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "$ac_config_links_1") CONFIG_LINKS="$CONFIG_LINKS $ac_config_links_1" ;; + "Makefile.sim") CONFIG_FILES="$CONFIG_FILES Makefile.sim:Makefile.in" ;; + "Make-common.sim") CONFIG_FILES="$CONFIG_FILES Make-common.sim:../common/Make-common.in" ;; + ".gdbinit") CONFIG_FILES="$CONFIG_FILES .gdbinit:../common/gdbinit.in" ;; + "Makefile") CONFIG_COMMANDS="$CONFIG_COMMANDS Makefile" ;; + "stamp-h") CONFIG_COMMANDS="$CONFIG_COMMANDS stamp-h" ;; + + *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\).*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\).*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || as_fn_error "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then + break + elif $ac_last_try; then + as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$tmp/config.h" "$ac_file" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error "could not create -" "$LINENO" 5 + fi + ;; + :L) + # + # CONFIG_LINK + # + + if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then + : + else + # Prefer the file from the source tree if names are identical. + if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then + ac_source=$srcdir/$ac_source + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5 +$as_echo "$as_me: linking $ac_source to $ac_file" >&6;} + + if test ! -r "$ac_source"; then + as_fn_error "$ac_source: file not found" "$LINENO" 5 + fi + rm -f "$ac_file" + + # Try a relative symlink, then a hard link, then a copy. + case $srcdir in + [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;; + *) ac_rel_source=$ac_top_build_prefix$ac_source ;; + esac + ln -s "$ac_rel_source" "$ac_file" 2>/dev/null || + ln "$ac_source" "$ac_file" 2>/dev/null || + cp -p "$ac_source" "$ac_file" || + as_fn_error "cannot link or copy $ac_source to $ac_file" "$LINENO" 5 + fi + ;; + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depdir":C) $SHELL $ac_aux_dir/mkinstalldirs $DEPDIR ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="" + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# If ld is used when linking, flag to hardcode \$libdir into a binary +# during linking. This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path=$lt_fix_srcfile_path + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + case $xsi_shell in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac +} + +# func_basename file +func_basename () +{ + func_basename_result="${1##*/}" +} + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}" +} + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +func_stripname () +{ + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"} +} + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=${1%%=*} + func_opt_split_arg=${1#*=} +} + +# func_lo2o object +func_lo2o () +{ + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=${1%.*}.lo +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $* )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + +_LT_EOF + ;; + *) # Bourne compatible functions. + cat << \_LT_EOF >> "$cfgfile" + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} + +# sed scripts: +my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' +my_sed_long_arg='1s/^-[^=]*=//' + +# func_opt_split +func_opt_split () +{ + func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"` + func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"` +} + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$@"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` +} + +_LT_EOF +esac + +case $lt_shell_append in + yes) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1+=\$2" +} +_LT_EOF + ;; + *) + cat << \_LT_EOF >> "$cfgfile" + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "$1=\$$1\$2" +} + +_LT_EOF + ;; + esac + + + sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + "Makefile":C) echo "Merging Makefile.sim+Make-common.sim into Makefile ..." + rm -f Makesim1.tmp Makesim2.tmp Makefile + sed -n -e '/^## COMMON_PRE_/,/^## End COMMON_PRE_/ p' <Make-common.sim >Makesim1.tmp + sed -n -e '/^## COMMON_POST_/,/^## End COMMON_POST_/ p' <Make-common.sim >Makesim2.tmp + sed -e '/^## COMMON_PRE_/ r Makesim1.tmp' \ + -e '/^## COMMON_POST_/ r Makesim2.tmp' \ + <Makefile.sim >Makefile + rm -f Makefile.sim Make-common.sim Makesim1.tmp Makesim2.tmp + ;; + "stamp-h":C) echo > stamp-h ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit $? +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + diff --git a/sim/aarch64/configure.ac b/sim/aarch64/configure.ac new file mode 100644 index 0000000..25342d4 --- /dev/null +++ b/sim/aarch64/configure.ac @@ -0,0 +1,39 @@ +dnl Process this file with autoconf to produce a configure script. + +dnl Copyright (C) 2015 Free Software Foundation, Inc. +dnl +dnl Contributed by Red Hat. +dnl +dnl This file is part of GDB. + +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +AC_PREREQ(2.64)dnl +AC_INIT(Makefile.in) +sinclude(../common/acinclude.m4) + +SIM_AC_COMMON + +SIM_AC_OPTION_ENDIAN +## We use NONSTRICT_ALIGNMENT as the default because AArch64 only +## enforces 4-byte alignment, even for 8-byte reads/writes. The +## common core does not support this, so we opt for non-strict +## alignment instead. +SIM_AC_OPTION_ALIGNMENT(NONSTRICT_ALIGNMENT,NONSTRICT_ALIGNMENT) +SIM_AC_OPTION_HOSTENDIAN +SIM_AC_OPTION_ENVIRONMENT +SIM_AC_OPTION_INLINE +SIM_AC_OPTION_WARNINGS + +SIM_AC_OUTPUT diff --git a/sim/aarch64/cpustate.c b/sim/aarch64/cpustate.c new file mode 100644 index 0000000..5fddc30 --- /dev/null +++ b/sim/aarch64/cpustate.c @@ -0,0 +1,557 @@ +/* cpustate.h -- Prototypes for AArch64 simulator functions. + + Copyright (C) 2015 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + 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; either version 3 of the License, or + (at your option) any later version. + + 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, see <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> + +#include "sim-main.h" +#include "cpustate.h" +#include "simulator.h" + +/* Some operands are allowed to access the stack pointer (reg 31). + For others a read from r31 always returns 0, and a write to r31 is ignored. */ +#define reg_num(reg) (((reg) == R31 && !r31_is_sp) ? 32 : (reg)) + +void +aarch64_set_reg_u64 (sim_cpu *cpu, GReg reg, int r31_is_sp, uint64_t val) +{ + if (reg == R31 && ! r31_is_sp) + { + TRACE_REGISTER (cpu, " GR[31] NOT CHANGED!"); + return; + } + + if (val != cpu->gr[reg].u64) + TRACE_REGISTER (cpu, + " GR[%2d] changes from %16" PRIx64 " to %16" PRIx64, + reg, cpu->gr[reg].u64, val); + + cpu->gr[reg].u64 = val; +} + +void +aarch64_set_reg_s64 (sim_cpu *cpu, GReg reg, int r31_is_sp, int64_t val) +{ + if (reg == R31 && ! r31_is_sp) + { + TRACE_REGISTER (cpu, " GR[31] NOT CHANGED!"); + return; + } + + if (val != cpu->gr[reg].s64) + TRACE_REGISTER (cpu, + " GR[%2d] changes from %16" PRIx64 " to %16" PRIx64, + reg, cpu->gr[reg].s64, val); + + cpu->gr[reg].s64 = val; +} + +uint64_t +aarch64_get_reg_u64 (sim_cpu *cpu, GReg reg, int r31_is_sp) +{ + return cpu->gr[reg_num(reg)].u64; +} + +int64_t +aarch64_get_reg_s64 (sim_cpu *cpu, GReg reg, int r31_is_sp) +{ + return cpu->gr[reg_num(reg)].s64; +} + +uint32_t +aarch64_get_reg_u32 (sim_cpu *cpu, GReg reg, int r31_is_sp) +{ + return cpu->gr[reg_num(reg)].u32; +} + +int32_t +aarch64_get_reg_s32 (sim_cpu *cpu, GReg reg, int r31_is_sp) +{ + return cpu->gr[reg_num(reg)].s32; +} + +uint32_t +aarch64_get_reg_u16 (sim_cpu *cpu, GReg reg, int r31_is_sp) +{ + return cpu->gr[reg_num(reg)].u16; +} + +int32_t +aarch64_get_reg_s16 (sim_cpu *cpu, GReg reg, int r31_is_sp) +{ + return cpu->gr[reg_num(reg)].s16; +} + +uint32_t +aarch64_get_reg_u8 (sim_cpu *cpu, GReg reg, int r31_is_sp) +{ + return cpu->gr[reg_num(reg)].u8; +} + +int32_t +aarch64_get_reg_s8 (sim_cpu *cpu, GReg reg, int r31_is_sp) +{ + return cpu->gr[reg_num(reg)].s8; +} + +uint64_t +aarch64_get_PC (sim_cpu *cpu) +{ + return cpu->pc; +} + +uint64_t +aarch64_get_next_PC (sim_cpu *cpu) +{ + return cpu->nextpc; +} + +void +aarch64_set_next_PC (sim_cpu *cpu, uint64_t next) +{ + if (next != cpu->nextpc + 4) + TRACE_REGISTER (cpu, + " NextPC changes from %16" PRIx64 " to %16" PRIx64, + cpu->nextpc, next); + + cpu->nextpc = next; +} + +void +aarch64_set_next_PC_by_offset (sim_cpu *cpu, int64_t offset) +{ + if (cpu->pc + offset != cpu->nextpc + 4) + TRACE_REGISTER (cpu, + " NextPC changes from %16" PRIx64 " to %16" PRIx64, + cpu->nextpc, cpu->pc + offset); + + cpu->nextpc = cpu->pc + offset; +} + +/* Install nextpc as current pc. */ +void +aarch64_update_PC (sim_cpu *cpu) +{ + cpu->pc = cpu->nextpc; + /* Rezero the register we hand out when asked for ZR just in case it + was used as the destination for a write by the previous + instruction. */ + cpu->gr[32].u64 = 0UL; +} + +/* This instruction can be used to save the next PC to LR + just before installing a branch PC. */ +void +aarch64_save_LR (sim_cpu *cpu) +{ + if (cpu->gr[LR].u64 != cpu->nextpc) + TRACE_REGISTER (cpu, + " LR changes from %16" PRIx64 " to %16" PRIx64, + cpu->gr[LR].u64, cpu->nextpc); + + cpu->gr[LR].u64 = cpu->nextpc; +} + +static const char * +decode_cpsr (FlagMask flags) +{ + switch (flags & CPSR_ALL_FLAGS) + { + default: + case 0: return "----"; + case 1: return "---V"; + case 2: return "--C-"; + case 3: return "--CV"; + case 4: return "-Z--"; + case 5: return "-Z-V"; + case 6: return "-ZC-"; + case 7: return "-ZCV"; + case 8: return "N---"; + case 9: return "N--V"; + case 10: return "N-C-"; + case 11: return "N-CV"; + case 12: return "NZ--"; + case 13: return "NZ-V"; + case 14: return "NZC-"; + case 15: return "NZCV"; + } +} + +/* Retrieve the CPSR register as an int. */ +uint32_t +aarch64_get_CPSR (sim_cpu *cpu) +{ + return cpu->CPSR; +} + +/* Set the CPSR register as an int. */ +void +aarch64_set_CPSR (sim_cpu *cpu, uint32_t new_flags) +{ + if (TRACE_REGISTER_P (cpu)) + { + if (cpu->CPSR != new_flags) + TRACE_REGISTER (cpu, + " CPSR changes from %s to %s", + decode_cpsr (cpu->CPSR), decode_cpsr (new_flags)); + else + TRACE_REGISTER (cpu, + " CPSR stays at %s", decode_cpsr (cpu->CPSR)); + } + + cpu->CPSR = new_flags & CPSR_ALL_FLAGS; +} + +/* Read a specific subset of the CPSR as a bit pattern. */ +uint32_t +aarch64_get_CPSR_bits (sim_cpu *cpu, FlagMask mask) +{ + return cpu->CPSR & mask; +} + +/* Assign a specific subset of the CPSR as a bit pattern. */ +void +aarch64_set_CPSR_bits (sim_cpu *cpu, uint32_t mask, uint32_t value) +{ + uint32_t old_flags = cpu->CPSR; + + mask &= CPSR_ALL_FLAGS; + cpu->CPSR &= ~ mask; + cpu->CPSR |= (value & mask); + + if (old_flags != cpu->CPSR) + TRACE_REGISTER (cpu, + " CPSR changes from %s to %s", + decode_cpsr (old_flags), decode_cpsr (cpu->CPSR)); +} + +/* Test the value of a single CPSR returned as non-zero or zero. */ +uint32_t +aarch64_test_CPSR_bit (sim_cpu *cpu, FlagMask bit) +{ + return cpu->CPSR & bit; +} + +/* Set a single flag in the CPSR. */ +void +aarch64_set_CPSR_bit (sim_cpu *cpu, FlagMask bit) +{ + uint32_t old_flags = cpu->CPSR; + + cpu->CPSR |= (bit & CPSR_ALL_FLAGS); + + if (old_flags != cpu->CPSR) + TRACE_REGISTER (cpu, + " CPSR changes from %s to %s", + decode_cpsr (old_flags), decode_cpsr (cpu->CPSR)); +} + +/* Clear a single flag in the CPSR. */ +void +aarch64_clear_CPSR_bit (sim_cpu *cpu, FlagMask bit) +{ + uint32_t old_flags = cpu->CPSR; + + cpu->CPSR &= ~(bit & CPSR_ALL_FLAGS); + + if (old_flags != cpu->CPSR) + TRACE_REGISTER (cpu, + " CPSR changes from %s to %s", + decode_cpsr (old_flags), decode_cpsr (cpu->CPSR)); +} + +float +aarch64_get_FP_float (sim_cpu *cpu, VReg reg) +{ + return cpu->fr[reg].s; +} + +double +aarch64_get_FP_double (sim_cpu *cpu, VReg reg) +{ + return cpu->fr[reg].d; +} + +void +aarch64_get_FP_long_double (sim_cpu *cpu, VReg reg, FRegister *a) +{ + a->v[0] = cpu->fr[reg].v[0]; + a->v[1] = cpu->fr[reg].v[1]; +} + +void +aarch64_set_FP_float (sim_cpu *cpu, VReg reg, float val) +{ + if (val != cpu->fr[reg].s) + TRACE_REGISTER (cpu, + " FR[%d] changes from %f to %f", + reg, cpu->fr[reg].s, val); + + cpu->fr[reg].s = val; +} + +void +aarch64_set_FP_double (sim_cpu *cpu, VReg reg, double val) +{ + if (val != cpu->fr[reg].d) + TRACE_REGISTER (cpu, + " FR[%d] changes from %f to %f", + reg, cpu->fr[reg].d, val); + + cpu->fr[reg].d = val; +} + +void +aarch64_set_FP_long_double (sim_cpu *cpu, VReg reg, FRegister a) +{ + if (cpu->fr[reg].v[0] != a.v[0] + || cpu->fr[reg].v[1] != a.v[1]) + TRACE_REGISTER (cpu, + " FR[%d] changes from [%0lx %0lx] to [%lx %lx] ", + reg, + cpu->fr[reg].v[0], cpu->fr[reg].v[1], + a.v[0], a.v[1]); + + cpu->fr[reg].v[0] = a.v[0]; + cpu->fr[reg].v[1] = a.v[1]; +} + +uint64_t +aarch64_get_vec_u64 (sim_cpu *cpu, VReg reg, unsigned element) +{ + return cpu->fr[reg].v[element]; +} + +uint32_t +aarch64_get_vec_u32 (sim_cpu *cpu, VReg regno, unsigned element) +{ + return cpu->fr[regno].w[element]; +} + +uint16_t +aarch64_get_vec_u16 (sim_cpu *cpu, VReg regno, unsigned element) +{ + return cpu->fr[regno].h[element]; +} + +uint8_t +aarch64_get_vec_u8 (sim_cpu *cpu, VReg regno, unsigned element) +{ + return cpu->fr[regno].b[element]; +} + +void +aarch64_set_vec_u64 (sim_cpu * cpu, + VReg regno, + unsigned element, + uint64_t value) +{ + if (value != cpu->fr[regno].v[element]) + TRACE_REGISTER (cpu, + " VR[%2d].<long>[%d] changes from %16" PRIx64 + " to %16" PRIx64, + regno, element, cpu->fr[regno].v[element], value); + + cpu->fr[regno].v[element] = value; +} + +void +aarch64_set_vec_u32 (sim_cpu * cpu, + VReg regno, + unsigned element, + uint32_t value) +{ + if (value != cpu->fr[regno].w[element]) + TRACE_REGISTER (cpu, + " VR[%2d].<word>[%d] changes from %8x to %8x", + regno, element, cpu->fr[regno].w[element], value); + + cpu->fr[regno].w[element] = value; +} + +void +aarch64_set_vec_u16 (sim_cpu * cpu, + VReg regno, + unsigned element, + uint16_t value) +{ + if (value != cpu->fr[regno].h[element]) + TRACE_REGISTER (cpu, + " VR[%2d].<half>[%d] changes from %4x to %4x", + regno, element, cpu->fr[regno].h[element], value); + + cpu->fr[regno].h[element] = value; +} + +void +aarch64_set_vec_u8 (sim_cpu *cpu, VReg regno, unsigned element, uint8_t value) +{ + if (value != cpu->fr[regno].b[element]) + TRACE_REGISTER (cpu, + " VR[%2d].<byte>[%d] changes from %x to %x", + regno, element, cpu->fr[regno].b[element], value); + + cpu->fr[regno].b[element] = value; +} + +void +aarch64_set_FPSR (sim_cpu *cpu, uint32_t value) +{ + if (cpu->FPSR != value) + TRACE_REGISTER (cpu, + " FPSR changes from %x to %x", cpu->FPSR, value); + + cpu->FPSR = value & FPSR_ALL_FPSRS; +} + +uint32_t +aarch64_get_FPSR (sim_cpu *cpu) +{ + return cpu->FPSR; +} + +void +aarch64_set_FPSR_bits (sim_cpu *cpu, uint32_t mask, uint32_t value) +{ + uint32_t old_FPSR = cpu->FPSR; + + mask &= FPSR_ALL_FPSRS; + cpu->FPSR &= ~mask; + cpu->FPSR |= (value & mask); + + if (cpu->FPSR != old_FPSR) + TRACE_REGISTER (cpu, + " FPSR changes from %x to %x", old_FPSR, cpu->FPSR); +} + +uint32_t +aarch64_get_FPSR_bits (sim_cpu *cpu, uint32_t mask) +{ + mask &= FPSR_ALL_FPSRS; + return cpu->FPSR & mask; +} + +int +aarch64_test_FPSR_bit (sim_cpu *cpu, FPSRMask flag) +{ + return cpu->FPSR & flag; +} + +float +aarch64_get_vec_float (sim_cpu *cpu, VReg v, unsigned e) +{ + return cpu->fr[v].S[e]; +} + +double +aarch64_get_vec_double (sim_cpu *cpu, VReg v, unsigned e) +{ + return cpu->fr[v].D[e]; +} + +void +aarch64_set_vec_float (sim_cpu *cpu, VReg v, unsigned e, float f) +{ + if (f != cpu->fr[v].S[e]) + TRACE_REGISTER (cpu, + " VR[%2d].<float>[%d] changes from %f to %f", + v, e, cpu->fr[v].S[e], f); + + cpu->fr[v].S[e] = f; +} + +void +aarch64_set_vec_double (sim_cpu *cpu, VReg v, unsigned e, double d) +{ + if (d != cpu->fr[v].D[e]) + TRACE_REGISTER (cpu, + " VR[%2d].<double>[%d] changes from %f to %f", + v, e, cpu->fr[v].D[e], d); + + cpu->fr[v].D[e] = d; +} + +int64_t +aarch64_get_vec_s64 (sim_cpu *cpu, VReg regno, unsigned element) +{ + return cpu->fr[regno].V[element]; +} + +int32_t +aarch64_get_vec_s32 (sim_cpu *cpu, VReg regno, unsigned element) +{ + return cpu->fr[regno].W[element]; +} + +int16_t +aarch64_get_vec_s16 (sim_cpu *cpu, VReg regno, unsigned element) +{ + return cpu->fr[regno].H[element]; +} + +int8_t +aarch64_get_vec_s8 (sim_cpu *cpu, VReg regno, unsigned element) +{ + return cpu->fr[regno].B[element]; +} + +void +aarch64_set_vec_s64 (sim_cpu *cpu, VReg regno, unsigned element, int64_t value) +{ + if (value != cpu->fr[regno].V[element]) + TRACE_REGISTER (cpu, + " VR[%2d].<long>[%d] changes from %16" PRIx64 " to %16" PRIx64, + regno, element, cpu->fr[regno].V[element], value); + + cpu->fr[regno].V[element] = value; +} + +void +aarch64_set_vec_s32 (sim_cpu *cpu, VReg regno, unsigned element, int32_t value) +{ + if (value != cpu->fr[regno].W[element]) + TRACE_REGISTER (cpu, + " VR[%2d].<word>[%d] changes from %8x to %8x", + regno, element, cpu->fr[regno].W[element], value); + + cpu->fr[regno].W[element] = value; +} + +void +aarch64_set_vec_s16 (sim_cpu *cpu, VReg regno, unsigned element, int16_t value) +{ + if (value != cpu->fr[regno].H[element]) + TRACE_REGISTER (cpu, + " VR[%2d].<half>[%d] changes from %4x to %4x", + regno, element, cpu->fr[regno].H[element], value); + + cpu->fr[regno].H[element] = value; +} + +void +aarch64_set_vec_s8 (sim_cpu *cpu, VReg regno, unsigned element, int8_t value) +{ + if (value != cpu->fr[regno].B[element]) + TRACE_REGISTER (cpu, + " VR[%2d].<byte>[%d] changes from %x to %x", + regno, element, cpu->fr[regno].B[element], value); + + cpu->fr[regno].B[element] = value; +} diff --git a/sim/aarch64/cpustate.h b/sim/aarch64/cpustate.h new file mode 100644 index 0000000..8734423 --- /dev/null +++ b/sim/aarch64/cpustate.h @@ -0,0 +1,333 @@ +/* cpustate.h -- Prototypes for AArch64 cpu state functions. + + Copyright (C) 2015 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + 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; either version 3 of the License, or + (at your option) any later version. + + 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _CPU_STATE_H +#define _CPU_STATE_H + +#include <sys/types.h> +#include <stdint.h> +#include <inttypes.h> + +#include "gdb/remote-sim.h" + +/* Symbolic names used to identify general registers which also match + the registers indices in machine code. + + We have 32 general registers which can be read/written as 32 bit or + 64 bit sources/sinks and are appropriately referred to as Wn or Xn + in the assembly code. Some instructions mix these access modes + (e.g. ADD X0, X1, W2) so the implementation of the instruction + needs to *know* which type of read or write access is required. */ +typedef enum GReg +{ + R0, + R1, + R2, + R3, + R4, + R5, + R6, + R7, + R8, + R9, + R10, + R11, + R12, + R13, + R14, + R15, + R16, + R17, + R18, + R19, + R20, + R21, + R22, + R23, + R24, + R25, + R26, + R27, + R28, + R29, + R30, + R31, + FP = R29, + LR = R30, + SP = R31, + ZR = R31 +} GReg; + +/* Symbolic names used to refer to floating point registers which also + match the registers indices in machine code. + + We have 32 FP registers which can be read/written as 8, 16, 32, 64 + and 128 bit sources/sinks and are appropriately referred to as Bn, + Hn, Sn, Dn and Qn in the assembly code. Some instructions mix these + access modes (e.g. FCVT S0, D0) so the implementation of the + instruction needs to *know* which type of read or write access is + required. */ + +typedef enum VReg +{ + V0, + V1, + V2, + V3, + V4, + V5, + V6, + V7, + V8, + V9, + V10, + V11, + V12, + V13, + V14, + V15, + V16, + V17, + V18, + V19, + V20, + V21, + V22, + V23, + V24, + V25, + V26, + V27, + V28, + V29, + V30, + V31, +} VReg; + +/* All the different integer bit patterns for the components of a + general register are overlaid here using a union so as to allow all + reading and writing of the desired bits. + + N.B. the ARM spec says that when you write a 32 bit register you + are supposed to write the low 32 bits and zero the high 32 + bits. But we don't actually have to care about this because Java + will only ever consume the 32 bits value as a 64 bit quantity after + an explicit extend. */ +typedef union GRegisterValue +{ + int8_t s8; + int16_t s16; + int32_t s32; + int64_t s64; + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; +} GRegister; + +/* Float registers provide for storage of a single, double or quad + word format float in the same register. Single floats are not + paired within each double register as per 32 bit arm. Instead each + 128 bit register Vn embeds the bits for Sn, and Dn in the lower + quarter and half, respectively, of the bits for Qn. + + The upper bits can also be accessed as single or double floats by + the float vector operations using indexing e.g. V1.D[1], V1.S[3] + etc and, for SIMD operations using a horrible index range notation. + + The spec also talks about accessing float registers as half words + and bytes with Hn and Bn providing access to the low 16 and 8 bits + of Vn but it is not really clear what these bits represent. We can + probably ignore this for Java anyway. However, we do need to access + the raw bits at 32 and 64 bit resolution to load to/from integer + registers. + + Note - we do not use the long double type. Aliasing issues between + integer and float values mean that it is unreliable to use them. */ + +typedef union FRegisterValue +{ + float s; + double d; + + uint64_t v[2]; + uint32_t w[4]; + uint16_t h[8]; + uint8_t b[16]; + + int64_t V[2]; + int32_t W[4]; + int16_t H[8]; + int8_t B[16]; + + float S[4]; + double D[2]; + +} FRegister; + +/* Condition register bit select values. + + The order of bits here is important because some of + the flag setting conditional instructions employ a + bit field to populate the flags when a false condition + bypasses execution of the operation and we want to + be able to assign the flags register using the + supplied value. */ + +typedef enum FlagIdx +{ + V_IDX, + C_IDX, + Z_IDX, + N_IDX +} FlagIdx; + +typedef enum FlagMask +{ + V = 1 << V_IDX, + C = 1 << C_IDX, + Z = 1 << Z_IDX, + N = 1 << N_IDX +} FlagMask; + +#define CPSR_ALL_FLAGS (V | C | Z | N) + +typedef uint32_t FlagsRegister; + +/* FPSR register -- floating point status register + + This register includes IDC, IXC, UFC, OFC, DZC, IOC and QC bits, + and the floating point N, Z, C, V bits but the latter are unused in + aarch64 mode. the sim ignores QC for now. + + Bit positions are as per the ARMv7 FPSCR register + + IDC : 7 ==> Input Denormal (cumulative exception bit) + IXC : 4 ==> Inexact + UFC : 3 ==> Underflow + OFC : 2 ==> Overflow + DZC : 1 ==> Division by Zero + IOC : 0 ==> Invalid Operation + + The rounding mode is held in bits [23,22] defined as follows: + + 0b00 Round to Nearest (RN) mode + 0b01 Round towards Plus Infinity (RP) mode + 0b10 Round towards Minus Infinity (RM) mode + 0b11 Round towards Zero (RZ) mode. */ + +/* Indices for bits in the FPSR register value. */ +typedef enum FPSRIdx +{ + IO_IDX = 0, + DZ_IDX = 1, + OF_IDX = 2, + UF_IDX = 3, + IX_IDX = 4, + ID_IDX = 7 +} FPSRIdx; + +/* Corresponding bits as numeric values. */ +typedef enum FPSRMask +{ + IO = (1 << IO_IDX), + DZ = (1 << DZ_IDX), + OF = (1 << OF_IDX), + UF = (1 << UF_IDX), + IX = (1 << IX_IDX), + ID = (1 << ID_IDX) +} FPSRMask; + +#define FPSR_ALL_FPSRS (IO | DZ | OF | UF | IX | ID) + +/* General Register access functions. */ +extern uint64_t aarch64_get_reg_u64 (sim_cpu *, GReg, int); +extern int64_t aarch64_get_reg_s64 (sim_cpu *, GReg, int); +extern uint32_t aarch64_get_reg_u32 (sim_cpu *, GReg, int); +extern int32_t aarch64_get_reg_s32 (sim_cpu *, GReg, int); +extern uint32_t aarch64_get_reg_u16 (sim_cpu *, GReg, int); +extern int32_t aarch64_get_reg_s16 (sim_cpu *, GReg, int); +extern uint32_t aarch64_get_reg_u8 (sim_cpu *, GReg, int); +extern int32_t aarch64_get_reg_s8 (sim_cpu *, GReg, int); + +extern void aarch64_set_reg_u64 (sim_cpu *, GReg, int, uint64_t); +extern void aarch64_set_reg_s64 (sim_cpu *, GReg, int, int64_t); + +/* FP Register access functions. */ +extern float aarch64_get_FP_float (sim_cpu *, VReg); +extern double aarch64_get_FP_double (sim_cpu *, VReg); +extern void aarch64_get_FP_long_double (sim_cpu *, VReg, FRegister *); +extern void aarch64_set_FP_float (sim_cpu *, VReg, float); +extern void aarch64_set_FP_double (sim_cpu *, VReg, double); +extern void aarch64_set_FP_long_double (sim_cpu *, VReg, FRegister); + +/* PC register accessors. */ +extern uint64_t aarch64_get_PC (sim_cpu *); +extern uint64_t aarch64_get_next_PC (sim_cpu *); +extern void aarch64_set_next_PC (sim_cpu *, uint64_t); +extern void aarch64_set_next_PC_by_offset (sim_cpu *, int64_t); +extern void aarch64_update_PC (sim_cpu *); +extern void aarch64_save_LR (sim_cpu *); + +/* Instruction accessor - implemented as a + macro as we do not need to annotate it. */ +#define aarch64_get_instr(cpu) ((cpu)->instr) + +/* Flag register accessors. */ +extern uint32_t aarch64_get_CPSR (sim_cpu *); +extern void aarch64_set_CPSR (sim_cpu *, uint32_t); +extern uint32_t aarch64_get_CPSR_bits (sim_cpu *, uint32_t); +extern void aarch64_set_CPSR_bits (sim_cpu *, uint32_t, uint32_t); +extern uint32_t aarch64_test_CPSR_bit (sim_cpu *, FlagMask); +extern void aarch64_set_CPSR_bit (sim_cpu *, FlagMask); +extern void aarch64_clear_CPSR_bit (sim_cpu *, FlagMask); + +extern void aarch64_set_FPSR (sim_cpu *, uint32_t); +extern uint32_t aarch64_get_FPSR (sim_cpu *); +extern void aarch64_set_FPSR_bits (sim_cpu *, uint32_t, uint32_t); +extern uint32_t aarch64_get_FPSR_bits (sim_cpu *, uint32_t); +extern int aarch64_test_FPSR_bit (sim_cpu *, FPSRMask); + +/* Vector register accessors. */ +extern uint64_t aarch64_get_vec_u64 (sim_cpu *, VReg, unsigned); +extern uint32_t aarch64_get_vec_u32 (sim_cpu *, VReg, unsigned); +extern uint16_t aarch64_get_vec_u16 (sim_cpu *, VReg, unsigned); +extern uint8_t aarch64_get_vec_u8 (sim_cpu *, VReg, unsigned); +extern void aarch64_set_vec_u64 (sim_cpu *, VReg, unsigned, uint64_t); +extern void aarch64_set_vec_u32 (sim_cpu *, VReg, unsigned, uint32_t); +extern void aarch64_set_vec_u16 (sim_cpu *, VReg, unsigned, uint16_t); +extern void aarch64_set_vec_u8 (sim_cpu *, VReg, unsigned, uint8_t); + +extern int64_t aarch64_get_vec_s64 (sim_cpu *, VReg, unsigned); +extern int32_t aarch64_get_vec_s32 (sim_cpu *, VReg, unsigned); +extern int16_t aarch64_get_vec_s16 (sim_cpu *, VReg, unsigned); +extern int8_t aarch64_get_vec_s8 (sim_cpu *, VReg, unsigned); +extern void aarch64_set_vec_s64 (sim_cpu *, VReg, unsigned, int64_t); +extern void aarch64_set_vec_s32 (sim_cpu *, VReg, unsigned, int32_t); +extern void aarch64_set_vec_s16 (sim_cpu *, VReg, unsigned, int16_t); +extern void aarch64_set_vec_s8 (sim_cpu *, VReg, unsigned, int8_t); + +extern float aarch64_get_vec_float (sim_cpu *, VReg, unsigned); +extern double aarch64_get_vec_double (sim_cpu *, VReg, unsigned); +extern void aarch64_set_vec_float (sim_cpu *, VReg, unsigned, float); +extern void aarch64_set_vec_double (sim_cpu *, VReg, unsigned, double); + +#endif /* _CPU_STATE_H */ diff --git a/sim/aarch64/decode.h b/sim/aarch64/decode.h new file mode 100644 index 0000000..edb3c28 --- /dev/null +++ b/sim/aarch64/decode.h @@ -0,0 +1,418 @@ +/* decode.h -- Prototypes for AArch64 simulator decoder functions. + + Copyright (C) 2015 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + 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; either version 3 of the License, or + (at your option) any later version. + + 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _DECODE_H +#define _DECODE_H + +#include <sys/types.h> +#include "cpustate.h" + +/* Codes used in conditional instructions + + These are passed to conditional operations to identify which + condition to test for. */ + +typedef enum CondCode +{ + EQ = 0x0, /* meaning Z == 1 */ + NE = 0x1, /* meaning Z == 0 */ + HS = 0x2, /* meaning C == 1 */ + CS = HS, + LO = 0x3, /* meaning C == 0 */ + CC = LO, + MI = 0x4, /* meaning N == 1 */ + PL = 0x5, /* meaning N == 0 */ + VS = 0x6, /* meaning V == 1 */ + VC = 0x7, /* meaning V == 0 */ + HI = 0x8, /* meaning C == 1 && Z == 0 */ + LS = 0x9, /* meaning !(C == 1 && Z == 0) */ + GE = 0xa, /* meaning N == V */ + LT = 0xb, /* meaning N != V */ + GT = 0xc, /* meaning Z == 0 && N == V */ + LE = 0xd, /* meaning !(Z == 0 && N == V) */ + AL = 0xe, /* meaning ANY */ + NV = 0xf /* ditto */ +} CondCode; + +/* Certain addressing modes for load require pre or post writeback of + the computed address to a base register. */ + +typedef enum WriteBack +{ + Post = 0, + Pre = 1, + NoWriteBack = -1 +} WriteBack; + +/* Certain addressing modes for load require an offset to + be optionally scaled so the decode needs to pass that + through to the execute routine. */ + +typedef enum Scaling +{ + Unscaled = 0, + Scaled = 1, + NoScaling = -1 +} Scaling; + +/* When we do have to scale we do so by shifting using + log(bytes in data element - 1) as the shift count. + so we don't have to scale offsets when loading + bytes. */ + +typedef enum ScaleShift +{ + ScaleShift16 = 1, + ScaleShift32 = 2, + ScaleShift64 = 3, + ScaleShift128 = 4 +} ScaleShift; + +/* One of the addressing modes for load requires a 32-bit register + value to be either zero- or sign-extended for these instructions + UXTW or SXTW should be passed. + + Arithmetic register data processing operations can optionally + extend a portion of the second register value for these + instructions the value supplied must identify the portion of the + register which is to be zero- or sign-exended. */ + +typedef enum Extension +{ + UXTB = 0, + UXTH = 1, + UXTW = 2, + UXTX = 3, + SXTB = 4, + SXTH = 5, + SXTW = 6, + SXTX = 7, + NoExtension = -1 +} Extension; + +/* Arithmetic and logical register data processing operations + optionally perform a shift on the second register value. */ + +typedef enum Shift +{ + LSL = 0, + LSR = 1, + ASR = 2, + ROR = 3 +} Shift; + +/* Bit twiddling helpers for instruction decode. */ + +/* 32 bit mask with bits [hi,...,lo] set. */ +static inline uint32_t +mask32 (int hi, int lo) +{ + int nbits = (hi + 1) - lo; + return ((1 << nbits) - 1) << lo; +} + +/* 64 bit mask with bits [hi,...,lo] set. */ +static inline uint64_t +mask64 (int hi, int lo) +{ + int nbits = (hi + 1) - lo; + return ((1L << nbits) - 1) << lo; +} + +/* Pick bits [hi,...,lo] from val. */ +static inline uint32_t +pick32 (uint32_t val, int hi, int lo) +{ + return val & mask32 (hi, lo); +} + +/* Pick bits [hi,...,lo] from val. */ +static inline uint64_t +pick64 (uint64_t val, int hi, int lo) +{ + return val & mask64 (hi, lo); +} + +/* Pick bits [hi,...,lo] from val and shift to [(hi-(newlo - lo)),newlo]. */ +static inline uint32_t +pickshift32 (uint32_t val, int hi, int lo, int newlo) +{ + uint32_t bits = pick32 (val, hi, lo); + + if (lo < newlo) + return bits << (newlo - lo); + + return bits >> (lo - newlo); +} + +/* Mask [hi,lo] and shift down to start at bit 0. */ +static inline uint32_t +pickbits32 (uint32_t val, int hi, int lo) +{ + return pick32 (val, hi, lo) >> lo; +} + +/* Mask [hi,lo] and shift down to start at bit 0. */ +static inline uint64_t +pickbits64 (uint64_t val, int hi, int lo) +{ + return pick64 (val, hi, lo) >> lo; +} + +/* Decode registers, immediates and constants of various types. */ + +static inline GReg +greg (uint32_t val, int lo) +{ + return (GReg) pickbits32 (val, lo + 4, lo); +} + +static inline VReg +vreg (uint32_t val, int lo) +{ + return (VReg) pickbits32 (val, lo + 4, lo); +} + +static inline uint32_t +uimm (uint32_t val, int hi, int lo) +{ + return pickbits32 (val, hi, lo); +} + +static inline int32_t +simm32 (uint32_t val, int hi, int lo) +{ + union + { + uint32_t u; + int32_t n; + } x; + + x.u = val << (31 - hi); + return x.n >> (31 - hi + lo); +} + +static inline int64_t +simm64 (uint64_t val, int hi, int lo) +{ + union + { + uint64_t u; + int64_t n; + } x; + + x.u = val << (63 - hi); + return x.n >> (63 - hi + lo); +} + +static inline Shift +shift (uint32_t val, int lo) +{ + return (Shift) pickbits32 (val, lo + 1, lo); +} + +static inline Extension +extension (uint32_t val, int lo) +{ + return (Extension) pickbits32 (val, lo + 2, lo); +} + +static inline Scaling +scaling (uint32_t val, int lo) +{ + return (Scaling) pickbits32 (val, lo, lo); +} + +static inline WriteBack +writeback (uint32_t val, int lo) +{ + return (WriteBack) pickbits32 (val, lo, lo); +} + +static inline CondCode +condcode (uint32_t val, int lo) +{ + return (CondCode) pickbits32 (val, lo + 3, lo); +} + +/* Operation decode. + Bits [28,24] are the primary dispatch vector. */ + +static inline uint32_t +dispatchGroup (uint32_t val) +{ + return pickshift32 (val, 28, 25, 0); +} + +/* The 16 possible values for bits [28,25] identified by tags which + map them to the 5 main instruction groups LDST, DPREG, ADVSIMD, + BREXSYS and DPIMM. + + An extra group PSEUDO is included in one of the unallocated ranges + for simulator-specific pseudo-instructions. */ + +enum DispatchGroup +{ + GROUP_PSEUDO_0000, + GROUP_UNALLOC_0001, + GROUP_UNALLOC_0010, + GROUP_UNALLOC_0011, + GROUP_LDST_0100, + GROUP_DPREG_0101, + GROUP_LDST_0110, + GROUP_ADVSIMD_0111, + GROUP_DPIMM_1000, + GROUP_DPIMM_1001, + GROUP_BREXSYS_1010, + GROUP_BREXSYS_1011, + GROUP_LDST_1100, + GROUP_DPREG_1101, + GROUP_LDST_1110, + GROUP_ADVSIMD_1111 +}; + +/* Bits [31, 29] of a Pseudo are the secondary dispatch vector. */ + +static inline uint32_t +dispatchPseudo (uint32_t val) +{ + return pickshift32 (val, 31, 29, 0); +} + +/* The 8 possible values for bits [31,29] in a Pseudo Instruction. + Bits [28,25] are always 0000. */ + +enum DispatchPseudo +{ + PSEUDO_UNALLOC_000, /* Unallocated. */ + PSEUDO_UNALLOC_001, /* Ditto. */ + PSEUDO_UNALLOC_010, /* Ditto. */ + PSEUDO_UNALLOC_011, /* Ditto. */ + PSEUDO_UNALLOC_100, /* Ditto. */ + PSEUDO_UNALLOC_101, /* Ditto. */ + PSEUDO_CALLOUT_110, /* CALLOUT -- bits [24,0] identify call/ret sig. */ + PSEUDO_HALT_111 /* HALT -- bits [24, 0] identify halt code. */ +}; + +/* Bits [25, 23] of a DPImm are the secondary dispatch vector. */ + +static inline uint32_t +dispatchDPImm (uint32_t instr) +{ + return pickshift32 (instr, 25, 23, 0); +} + +/* The 8 possible values for bits [25,23] in a Data Processing Immediate + Instruction. Bits [28,25] are always 100_. */ + +enum DispatchDPImm +{ + DPIMM_PCADR_000, /* PC-rel-addressing. */ + DPIMM_PCADR_001, /* Ditto. */ + DPIMM_ADDSUB_010, /* Add/Subtract (immediate). */ + DPIMM_ADDSUB_011, /* Ditto. */ + DPIMM_LOG_100, /* Logical (immediate). */ + DPIMM_MOV_101, /* Move Wide (immediate). */ + DPIMM_BITF_110, /* Bitfield. */ + DPIMM_EXTR_111 /* Extract. */ +}; + +/* Bits [29,28:26] of a LS are the secondary dispatch vector. */ + +static inline uint32_t +dispatchLS (uint32_t instr) +{ + return ( pickshift32 (instr, 29, 28, 1) + | pickshift32 (instr, 26, 26, 0)); +} + +/* The 8 possible values for bits [29,28:26] in a Load/Store + Instruction. Bits [28,25] are always _1_0. */ + +enum DispatchLS +{ + LS_EXCL_000, /* Load/store exclusive (includes some unallocated). */ + LS_ADVSIMD_001, /* AdvSIMD load/store (various -- includes some unallocated). */ + LS_LIT_010, /* Load register literal (includes some unallocated). */ + LS_LIT_011, /* Ditto. */ + LS_PAIR_100, /* Load/store register pair (various). */ + LS_PAIR_101, /* Ditto. */ + LS_OTHER_110, /* Other load/store formats. */ + LS_OTHER_111 /* Ditto. */ +}; + +/* Bits [28:24:21] of a DPReg are the secondary dispatch vector. */ + +static inline uint32_t +dispatchDPReg (uint32_t instr) +{ + return ( pickshift32 (instr, 28, 28, 2) + | pickshift32 (instr, 24, 24, 1) + | pickshift32 (instr, 21, 21, 0)); +} + +/* The 8 possible values for bits [28:24:21] in a Data Processing + Register Instruction. Bits [28,25] are always _101. */ + +enum DispatchDPReg +{ + DPREG_LOG_000, /* Logical (shifted register). */ + DPREG_LOG_001, /* Ditto. */ + DPREG_ADDSHF_010, /* Add/subtract (shifted register). */ + DPREG_ADDEXT_011, /* Add/subtract (extended register). */ + DPREG_ADDCOND_100, /* Add/subtract (with carry) AND + Cond compare/select AND + Data Processing (1/2 source). */ + DPREG_UNALLOC_101, /* Unallocated. */ + DPREG_3SRC_110, /* Data Processing (3 source). */ + DPREG_3SRC_111 /* Data Processing (3 source). */ +}; + +/* bits [31,29] of a BrExSys are the secondary dispatch vector. */ + +static inline uint32_t +dispatchBrExSys (uint32_t instr) +{ + return pickbits32 (instr, 31, 29); +} + +/* The 8 possible values for bits [31,29] in a Branch/Exception/System + Instruction. Bits [28,25] are always 101_. */ + +enum DispatchBr +{ + BR_IMM_000, /* Unconditional branch (immediate). */ + BR_IMMCMP_001, /* Compare & branch (immediate) AND + Test & branch (immediate). */ + BR_IMMCOND_010, /* Conditional branch (immediate) AND Unallocated. */ + BR_UNALLOC_011, /* Unallocated. */ + BR_IMM_100, /* Unconditional branch (immediate). */ + BR_IMMCMP_101, /* Compare & branch (immediate) AND + Test & branch (immediate). */ + BR_REG_110, /* Unconditional branch (register) AND System AND + Excn gen AND Unallocated. */ + BR_UNALLOC_111 /* Unallocated. */ +}; + +/* TODO still need to provide secondary decode and dispatch for + AdvSIMD Insructions with instr[28,25] = 0111 or 1111. */ + +#endif /* _DECODE_H */ diff --git a/sim/aarch64/interp.c b/sim/aarch64/interp.c new file mode 100644 index 0000000..46ff994 --- /dev/null +++ b/sim/aarch64/interp.c @@ -0,0 +1,483 @@ +/* interp.c -- AArch64 sim interface to GDB. + + Copyright (C) 2015 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + 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; either version 3 of the License, or + (at your option) any later version. + + 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, see <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include <stdio.h> +#include <assert.h> +#include <signal.h> +#include <string.h> +#include <ctype.h> +#include <stdlib.h> + +#include "ansidecl.h" +#include "gdb/callback.h" +#include "gdb/remote-sim.h" +#include "gdb/signals.h" +#include "gdb/sim-aarch64.h" + +#include "sim-main.h" +#include "sim-options.h" +#include "memory.h" +#include "simulator.h" + +#include "dis-asm.h" + +static struct disassemble_info info; +static unsigned long symcount = 0; +static asymbol ** symtab = NULL; + +/* FIXME: 1000 characters should be enough to hold the disassembled + instruction plus any comments that come after it. But maybe with + C++ programs this might not be enough. Not sure if it is worth + adding logic to dynamically grow the buffer though. */ +static char opbuf[1000]; + +static int op_printf (void *, const char *, ...) ATTRIBUTE_FPTR_PRINTF_2; + +static int +op_printf (void *stream ATTRIBUTE_UNUSED, const char *fmt, ...) +{ + size_t space_remaining; + int ret; + va_list ap; + + space_remaining = sizeof (opbuf) - strlen (opbuf); + va_start (ap, fmt); + /* Instead of printing to stream we store the text in opbuf. + This allows us to use the sim_io_eprintf routine to output + the text in aarch64_print_insn. */ + ret = vsnprintf (opbuf + strlen (opbuf), space_remaining, fmt, ap); + va_end (ap); + return ret; +} + +void +aarch64_print_insn (SIM_DESC sd, uint64_t addr) +{ + int size; + + opbuf[0] = 0; + size = print_insn_aarch64 (addr, & info); + sim_io_eprintf (sd, " %*s\n", size, opbuf); +} + +static int +sim_dis_read (bfd_vma memaddr, + bfd_byte * ptr, + unsigned int length, + struct disassemble_info * info) +{ + aarch64_get_mem_blk (info->private_data, memaddr, (char *) ptr, length); + + return 0; +} + +/* Filter out (in place) symbols that are useless for disassembly. + COUNT is the number of elements in SYMBOLS. + Return the number of useful symbols. */ + +static unsigned long +remove_useless_symbols (asymbol **symbols, unsigned long count) +{ + asymbol **in_ptr = symbols; + asymbol **out_ptr = symbols; + + while (count-- > 0) + { + asymbol *sym = *in_ptr++; + + if (strstr (sym->name, "gcc2_compiled")) + continue; + if (sym->name == NULL || sym->name[0] == '\0') + continue; + if (sym->flags & (BSF_DEBUGGING)) + continue; + if ( bfd_is_und_section (sym->section) + || bfd_is_com_section (sym->section)) + continue; + if (sym->name[0] == '$') + continue; + + *out_ptr++ = sym; + } + return out_ptr - symbols; +} + +static signed int +compare_symbols (const void *ap, const void *bp) +{ + const asymbol *a = * (const asymbol **) ap; + const asymbol *b = * (const asymbol **) bp; + + if (bfd_asymbol_value (a) > bfd_asymbol_value (b)) + return 1; + if (bfd_asymbol_value (a) < bfd_asymbol_value (b)) + return -1; + return 0; +} + +/* Find the name of the function at ADDR. */ +const char * +aarch64_get_func (uint64_t addr) +{ + int min, max; + + min = -1; + max = symcount; + while (min < max - 1) + { + int sym; + bfd_vma sa; + + sym = (min + max) / 2; + sa = bfd_asymbol_value (symtab[sym]); + + if (sa > addr) + max = sym; + else if (sa < addr) + min = sym; + else + { + min = sym; + break; + } + } + + if (min != -1) + return bfd_asymbol_name (symtab [min]); + + return ""; +} + +uint64_t +aarch64_get_sym_value (const char *name) +{ + unsigned long i; + + for (i = 0; i < symcount; i++) + if (strcmp (bfd_asymbol_name (symtab[i]), name) == 0) + return bfd_asymbol_value (symtab[i]); + + return 0; +} + +SIM_RC +sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env) +{ + sim_cpu *cpu = STATE_CPU (sd, 0); + long storage; + bfd_vma addr = 0; + + if (abfd != NULL) + addr = bfd_get_start_address (abfd); + + aarch64_set_next_PC (cpu, addr); + aarch64_update_PC (cpu); + + /* Standalone mode (ie aarch64-elf-run) will take care of the argv + for us in sim_open() -> sim_parse_args(). But in debug mode (i.e. + 'target sim' with `aarch64-...-gdb`), we need to handle it. */ + if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG) + { + freeargv (STATE_PROG_ARGV (sd)); + STATE_PROG_ARGV (sd) = dupargv (argv); + } + + memset (& info, 0, sizeof (info)); + init_disassemble_info (& info, NULL, op_printf); + info.read_memory_func = sim_dis_read; + info.arch = bfd_get_arch (abfd); + info.mach = bfd_get_mach (abfd); + info.private_data = cpu; + if (info.mach == 0) + info.arch = bfd_arch_aarch64; + disassemble_init_for_target (& info); + + storage = bfd_get_symtab_upper_bound (abfd); + if (storage > 0) + { + symtab = (asymbol **) xmalloc (storage); + symcount = bfd_canonicalize_symtab (abfd, symtab); + symcount = remove_useless_symbols (symtab, symcount); + qsort (symtab, symcount, sizeof (asymbol *), compare_symbols); + } + + aarch64_init (cpu, bfd_get_start_address (abfd)); + + return SIM_RC_OK; +} + +/* Read the LENGTH bytes at BUF as a little-endian value. */ + +static bfd_vma +get_le (unsigned char *buf, unsigned int length) +{ + bfd_vma acc = 0; + + while (length -- > 0) + acc = (acc << 8) + buf[length]; + + return acc; +} + +/* Store VAL as a little-endian value in the LENGTH bytes at BUF. */ + +static void +put_le (unsigned char *buf, unsigned int length, bfd_vma val) +{ + int i; + + for (i = 0; i < length; i++) + { + buf[i] = val & 0xff; + val >>= 8; + } +} + +static int +check_regno (int regno) +{ + return 0 <= regno && regno < AARCH64_MAX_REGNO; +} + +static size_t +reg_size (int regno) +{ + if (regno == AARCH64_CPSR_REGNO || regno == AARCH64_FPSR_REGNO) + return 32; + return 64; +} + +static int +aarch64_reg_get (SIM_CPU *cpu, int regno, unsigned char *buf, int length) +{ + size_t size; + bfd_vma val; + + if (!check_regno (regno)) + return 0; + + size = reg_size (regno); + + if (length != size) + return 0; + + switch (regno) + { + case AARCH64_MIN_GR ... AARCH64_MAX_GR: + val = aarch64_get_reg_u64 (cpu, regno, 0); + break; + + case AARCH64_MIN_FR ... AARCH64_MAX_FR: + val = aarch64_get_FP_double (cpu, regno - 32); + break; + + case AARCH64_PC_REGNO: + val = aarch64_get_PC (cpu); + break; + + case AARCH64_CPSR_REGNO: + val = aarch64_get_CPSR (cpu); + break; + + case AARCH64_FPSR_REGNO: + val = aarch64_get_FPSR (cpu); + break; + + default: + sim_io_eprintf (CPU_STATE (cpu), + "sim: unrecognized register number: %d\n", regno); + return -1; + } + + put_le (buf, length, val); + + return size; +} + +static int +aarch64_reg_set (SIM_CPU *cpu, int regno, unsigned char *buf, int length) +{ + size_t size; + bfd_vma val; + + if (!check_regno (regno)) + return -1; + + size = reg_size (regno); + + if (length != size) + return -1; + + val = get_le (buf, length); + + switch (regno) + { + case AARCH64_MIN_GR ... AARCH64_MAX_GR: + aarch64_set_reg_u64 (cpu, regno, 1, val); + break; + + case AARCH64_MIN_FR ... AARCH64_MAX_FR: + aarch64_set_FP_double (cpu, regno - 32, (double) val); + break; + + case AARCH64_PC_REGNO: + aarch64_set_next_PC (cpu, val); + aarch64_update_PC (cpu); + break; + + case AARCH64_CPSR_REGNO: + aarch64_set_CPSR (cpu, val); + break; + + case AARCH64_FPSR_REGNO: + aarch64_set_FPSR (cpu, val); + break; + + default: + sim_io_eprintf (CPU_STATE (cpu), + "sim: unrecognized register number: %d\n", regno); + return 0; + } + + return size; +} + +static sim_cia +aarch64_pc_get (sim_cpu *cpu) +{ + return aarch64_get_PC (cpu); +} + +static void +aarch64_pc_set (sim_cpu *cpu, sim_cia pc) +{ + aarch64_set_next_PC (cpu, pc); + aarch64_update_PC (cpu); +} + +static void +free_state (SIM_DESC sd) +{ + if (STATE_MODULES (sd) != NULL) + sim_module_uninstall (sd); + sim_cpu_free_all (sd); + sim_state_free (sd); +} + +enum +{ + OPTION_DISAS = OPTION_START, +}; + +static SIM_RC +aarch64_option_handler (SIM_DESC sd ATTRIBUTE_UNUSED, + sim_cpu * current_cpu ATTRIBUTE_UNUSED, + int opt, + char * arg ATTRIBUTE_UNUSED, + int is_command ATTRIBUTE_UNUSED) +{ + switch (opt) + { + case OPTION_DISAS: + disas = TRUE; + return SIM_RC_OK; + + default: + sim_io_eprintf (sd, "Unknown AArch64 option %d\n", opt); + return SIM_RC_FAIL; + } +} + +static DECLARE_OPTION_HANDLER (aarch64_option_handler); + +const OPTION aarch64_options[] = +{ + { {"disas", no_argument, NULL, OPTION_DISAS }, + '\0', NULL, "Enable instruction disassembly", + aarch64_option_handler, NULL }, + + { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL } +}; + +SIM_DESC +sim_open (SIM_OPEN_KIND kind, + struct host_callback_struct * callback, + struct bfd * abfd, + char ** argv) +{ + int i; + sim_cpu *cpu; + SIM_DESC sd = sim_state_alloc (kind, callback); + + if (sd == NULL) + return sd; + + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + + sim_add_option_table (sd, NULL, aarch64_options); + + /* Perform the initialization steps one by one. */ + if (sim_cpu_alloc_all (sd, 1, 0) != SIM_RC_OK + || sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK + || sim_parse_args (sd, argv) != SIM_RC_OK + || sim_analyze_program (sd, + (STATE_PROG_ARGV (sd) != NULL + ? *STATE_PROG_ARGV (sd) + : NULL), abfd) != SIM_RC_OK + || sim_config (sd) != SIM_RC_OK + || sim_post_argv_init (sd) != SIM_RC_OK) + { + free_state (sd); + return NULL; + } + + aarch64_init_LIT_table (); + + assert (MAX_NR_PROCESSORS == 1); + cpu = STATE_CPU (sd, 0); + CPU_PC_FETCH (cpu) = aarch64_pc_get; + CPU_PC_STORE (cpu) = aarch64_pc_set; + CPU_REG_FETCH (cpu) = aarch64_reg_get; + CPU_REG_STORE (cpu) = aarch64_reg_set; + + /* Set SP, FP and PC to 0 and set LR to -1 + so we can detect a top-level return. */ + aarch64_set_reg_u64 (cpu, SP, 1, 0); + aarch64_set_reg_u64 (cpu, FP, 1, 0); + aarch64_set_reg_u64 (cpu, LR, 1, TOP_LEVEL_RETURN_PC); + aarch64_set_next_PC (cpu, 0); + aarch64_update_PC (cpu); + + /* Default to a 128 Mbyte (== 2^27) memory space. */ + sim_do_commandf (sd, "memory-size 0x8000000"); + + return sd; +} + +void +sim_engine_run (SIM_DESC sd, + int next_cpu_nr ATTRIBUTE_UNUSED, + int nr_cpus ATTRIBUTE_UNUSED, + int siggnal ATTRIBUTE_UNUSED) +{ + aarch64_run (sd); +} diff --git a/sim/aarch64/memory.c b/sim/aarch64/memory.c new file mode 100644 index 0000000..4df9360 --- /dev/null +++ b/sim/aarch64/memory.c @@ -0,0 +1,196 @@ +/* memory.c -- Memory accessor functions for the AArch64 simulator + + Copyright (C) 2015 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + 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; either version 3 of the License, or + (at your option) any later version. + + 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, see <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "bfd.h" +#include "libbfd.h" +#include "libiberty.h" +#include "elf/internal.h" +#include "elf/common.h" + +#include "memory.h" +#include "simulator.h" + +#include "sim-core.h" + +static inline void +mem_error (sim_cpu *cpu, const char *message, uint64_t addr) +{ + if (disas) + sim_io_eprintf (CPU_STATE (cpu), "\n"); + TRACE_MEMORY (cpu, "ERROR: %s: %" PRIx64, message, addr); +} + +#define FETCH_FUNC(RETURN_TYPE, ACCESS_TYPE, NAME, N) \ + RETURN_TYPE \ + aarch64_get_mem_##NAME (sim_cpu *cpu, uint64_t address) \ + { \ + return (RETURN_TYPE) sim_core_read_##N (cpu, 0, read_map, address); \ + } + +/* A variant of the FETCH_FUNC macro that uses unaligned reads. + The AArch64 only requires 4-byte alignment for 8-byte quantities + but the sim common core does not support this. */ +#define FETCH_FUNC_U(RETURN_TYPE, ACCESS_TYPE, NAME) \ + RETURN_TYPE \ + aarch64_get_mem_##NAME (sim_cpu *cpu, uint64_t address) \ + { \ + return (RETURN_TYPE) sim_core_read_unaligned_8 (cpu, 0, read_map, address); \ + } + +FETCH_FUNC_U (uint64_t, uint64_t, u64) +FETCH_FUNC_U (int64_t, int64_t, s64) +FETCH_FUNC (uint32_t, uint32_t, u32, 4) +FETCH_FUNC (int32_t, int32_t, s32, 4) +FETCH_FUNC (uint32_t, uint16_t, u16, 2) +FETCH_FUNC (int32_t, int16_t, s16, 2) +FETCH_FUNC (uint32_t, uint8_t, u8, 1) +FETCH_FUNC (int32_t, int8_t, s8, 1) +FETCH_FUNC (float, float, float, 4) +FETCH_FUNC_U (double, double, double) + +void +aarch64_get_mem_long_double (sim_cpu *cpu, uint64_t address, FRegister *a) +{ + a->v[0] = sim_core_read_unaligned_8 (cpu, 0, read_map, address); + a->v[1] = sim_core_read_unaligned_8 (cpu, 0, read_map, address + 8); +} + +#define STORE_FUNC(TYPE, NAME, N) \ + void \ + aarch64_set_mem_##NAME (sim_cpu *cpu, uint64_t address, TYPE value) \ + { \ + TRACE_MEMORY (cpu, \ + "write of %" PRIx64 " (%d bytes) to %" PRIx64, \ + (uint64_t) value, N, address); \ + \ + sim_core_write_unaligned_##N (cpu, 0, write_map, address, value); \ + } + +/* A variant of the STORE_FUNC macro that uses unaligned writes. + The AArch64 only requires 4-byte alignment for 8-byte quantities + but the sim common core does not support this. */ +#define STORE_FUNC_U(TYPE, NAME) \ + void \ + aarch64_set_mem_##NAME (sim_cpu *cpu, uint64_t address, TYPE value) \ + { \ + TRACE_MEMORY (cpu, \ + "write of %" PRIx64 " (8 bytes) to %" PRIx64, \ + (uint64_t) value, address); \ + \ + sim_core_write_unaligned_8 (cpu, 0, write_map, address, value); \ + } + +STORE_FUNC_U (uint64_t, u64) +STORE_FUNC_U (int64_t, s64) +STORE_FUNC (uint32_t, u32, 4) +STORE_FUNC (int32_t, s32, 4) +STORE_FUNC (uint16_t, u16, 2) +STORE_FUNC (int16_t, s16, 2) +STORE_FUNC (uint8_t, u8, 1) +STORE_FUNC (int8_t, s8, 1) +STORE_FUNC (float, float, 4) +STORE_FUNC_U (double, double) + +void +aarch64_set_mem_long_double (sim_cpu *cpu, uint64_t address, FRegister a) +{ + TRACE_MEMORY (cpu, + "write of long double %" PRIx64 " %" PRIx64 " to %" PRIx64, + a.v[0], a.v[1], address); + + sim_core_write_unaligned_8 (cpu, 0, write_map, address, a.v[0]); + sim_core_write_unaligned_8 (cpu, 0, write_map, address + 8, a.v[1]); +} + +void +aarch64_get_mem_blk (sim_cpu * cpu, + uint64_t address, + char * buffer, + unsigned length) +{ + unsigned len; + + len = sim_core_read_buffer (CPU_STATE (cpu), cpu, read_map, + buffer, address, length); + if (len == length) + return; + + memset (buffer, 0, length); + if (cpu) + mem_error (cpu, "read of non-existant mem block at", address); + + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), + sim_stopped, SIM_SIGBUS); +} + +const char * +aarch64_get_mem_ptr (sim_cpu *cpu, uint64_t address) +{ + char *addr = sim_core_trans_addr (CPU_STATE (cpu), cpu, read_map, address); + + if (addr == NULL) + { + mem_error (cpu, "request for non-existant mem addr of", address); + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), + sim_stopped, SIM_SIGBUS); + } + + return addr; +} + +/* We implement a combined stack and heap. That way the sbrk() + function in libgloss/aarch64/syscalls.c has a chance to detect + an out-of-memory condition by noticing a stack/heap collision. + + The heap starts at the end of loaded memory and carries on up + to an arbitary 2Gb limit. */ + +uint64_t +aarch64_get_heap_start (sim_cpu *cpu) +{ + uint64_t heap = aarch64_get_sym_value ("end"); + + if (heap == 0) + heap = aarch64_get_sym_value ("_end"); + if (heap == 0) + { + heap = STACK_TOP - 0x100000; + sim_io_eprintf (CPU_STATE (cpu), + "Unable to find 'end' symbol - using addr based " + "upon stack instead %" PRIx64 "\n", + heap); + } + return heap; +} + +uint64_t +aarch64_get_stack_start (sim_cpu *cpu) +{ + if (aarch64_get_heap_start (cpu) >= STACK_TOP) + mem_error (cpu, "executable is too big", aarch64_get_heap_start (cpu)); + return STACK_TOP; +} diff --git a/sim/aarch64/memory.h b/sim/aarch64/memory.h new file mode 100644 index 0000000..bbd3c6f --- /dev/null +++ b/sim/aarch64/memory.h @@ -0,0 +1,64 @@ +/* memory.h -- Prototypes for AArch64 memory accessor functions. + + Copyright (C) 2015 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + 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; either version 3 of the License, or + (at your option) any later version. + + 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _MEMORY_H +#define _MEMORY_H + +#include <sys/types.h> +#include "bfd.h" +#include "simulator.h" + +extern float aarch64_get_mem_float (sim_cpu *, uint64_t); +extern double aarch64_get_mem_double (sim_cpu *, uint64_t); +extern void aarch64_get_mem_long_double (sim_cpu *, uint64_t, FRegister *); + +extern uint64_t aarch64_get_mem_u64 (sim_cpu *, uint64_t); +extern int64_t aarch64_get_mem_s64 (sim_cpu *, uint64_t); +extern uint32_t aarch64_get_mem_u32 (sim_cpu *, uint64_t); +extern int32_t aarch64_get_mem_s32 (sim_cpu *, uint64_t); +extern uint32_t aarch64_get_mem_u16 (sim_cpu *, uint64_t); +extern int32_t aarch64_get_mem_s16 (sim_cpu *, uint64_t); +extern uint32_t aarch64_get_mem_u8 (sim_cpu *, uint64_t); +extern int32_t aarch64_get_mem_s8 (sim_cpu *, uint64_t); +extern void aarch64_get_mem_blk (sim_cpu *, uint64_t, char *, unsigned); +extern const char * aarch64_get_mem_ptr (sim_cpu *, uint64_t); + +extern void aarch64_set_mem_float (sim_cpu *, uint64_t, float); +extern void aarch64_set_mem_double (sim_cpu *, uint64_t, double); +extern void aarch64_set_mem_long_double (sim_cpu *, uint64_t, FRegister); + +extern void aarch64_set_mem_u64 (sim_cpu *, uint64_t, uint64_t); +extern void aarch64_set_mem_s64 (sim_cpu *, uint64_t, int64_t); +extern void aarch64_set_mem_u32 (sim_cpu *, uint64_t, uint32_t); +extern void aarch64_set_mem_s32 (sim_cpu *, uint64_t, int32_t); +extern void aarch64_set_mem_u16 (sim_cpu *, uint64_t, uint16_t); +extern void aarch64_set_mem_s16 (sim_cpu *, uint64_t, int16_t); +extern void aarch64_set_mem_u8 (sim_cpu *, uint64_t, uint8_t); +extern void aarch64_set_mem_s8 (sim_cpu *, uint64_t, int8_t); + +#define STACK_TOP 0x07FFFF00 + +extern uint64_t aarch64_get_heap_start (sim_cpu *); +extern uint64_t aarch64_get_stack_start (sim_cpu *); + +extern void mem_add_blk (sim_cpu *, uint64_t, char *, uint64_t, bfd_boolean); + +#endif /* _MEMORY_H */ diff --git a/sim/aarch64/sim-main.h b/sim/aarch64/sim-main.h new file mode 100644 index 0000000..7ad36fc --- /dev/null +++ b/sim/aarch64/sim-main.h @@ -0,0 +1,68 @@ +/* sim-main.h -- Interface with sim/common. + + Copyright (C) 2015 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + 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; either version 3 of the License, or + (at your option) any later version. + + 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _SIM_MAIN_H +#define _SIM_MAIN_H + +#include "sim-basics.h" +#include "sim-types.h" +#include "sim-base.h" +#include "sim-base.h" +#include "sim-io.h" +#include "cpustate.h" + +/* A per-core state structure. */ +struct _sim_cpu +{ + GRegister gr[33]; /* Extra register at index 32 is used to hold zero value. */ + FRegister fr[32]; + + uint64_t pc; + uint32_t CPSR; + uint32_t FPSR; + + uint64_t nextpc; + + uint32_t instr; + + sim_cpu_base base; +}; + +typedef enum +{ + AARCH64_MIN_GR = 0, + AARCH64_MAX_GR = 31, + AARCH64_MIN_FR = 32, + AARCH64_MAX_FR = 63, + AARCH64_PC_REGNO = 64, + AARCH64_CPSR_REGNO = 65, + AARCH64_FPSR_REGNO = 66, + AARCH64_MAX_REGNO = 67 +} aarch64_regno; + +/* The simulator state structure used to hold all global variables. */ +struct sim_state +{ + sim_cpu * cpu[MAX_NR_PROCESSORS]; + sim_state_base base; +}; + +#endif /* _SIM_MAIN_H */ diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c new file mode 100644 index 0000000..31c054c --- /dev/null +++ b/sim/aarch64/simulator.c @@ -0,0 +1,13047 @@ +/* simulator.c -- Interface for the AArch64 simulator. + + Copyright (C) 2015 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + 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; either version 3 of the License, or + (at your option) any later version. + + 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, see <http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <syscall.h> +#include <math.h> +#include <time.h> +#include <limits.h> + +#include "dis-asm.h" + +#include "simulator.h" +#include "cpustate.h" +#include "memory.h" + +#define NO_SP 0 +#define SP_OK 1 + +bfd_boolean disas = FALSE; + +#define TST(_flag) (aarch64_test_CPSR_bit (cpu, _flag)) +#define IS_SET(_X) ( TST (( _X ))) +#define IS_CLEAR(_X) (!TST (( _X ))) + +#define HALT_UNALLOC \ + do \ + { \ + if (TRACE_INSN_P (cpu)) \ + { \ + aarch64_print_insn (CPU_STATE (cpu), aarch64_get_PC (cpu)); \ + TRACE_INSN (cpu, \ + "Unallocated instruction detected at sim line %d,"\ + " exe addr %" PRIx64, \ + __LINE__, aarch64_get_PC (cpu)); \ + } \ + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),\ + sim_stopped, SIM_SIGILL); \ + } \ + while (0) + +#define HALT_NYI \ + do \ + { \ + if (TRACE_INSN_P (cpu)) \ + { \ + aarch64_print_insn (CPU_STATE (cpu), aarch64_get_PC (cpu)); \ + TRACE_INSN (cpu, \ + "Unimplemented instruction detected at sim line %d,"\ + " exe addr %" PRIx64, \ + __LINE__, aarch64_get_PC (cpu)); \ + } \ + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu),\ + sim_stopped, SIM_SIGABRT); \ + } \ + while (0) + +#define NYI_assert(HI, LO, EXPECTED) \ + do \ + { \ + if (uimm (aarch64_get_instr (cpu), (HI), (LO)) != (EXPECTED)) \ + HALT_NYI; \ + } \ + while (0) + +#define HALT_UNREACHABLE \ + do \ + { \ + TRACE_EVENTS (cpu, "ISE: unreachable code point"); \ + sim_engine_abort (NULL, cpu, aarch64_get_PC (cpu), "Internal Error"); \ + } \ + while (0) + +/* Helper functions used by expandLogicalImmediate. */ + +/* for i = 1, ... N result<i-1> = 1 other bits are zero */ +static inline uint64_t +ones (int N) +{ + return (N == 64 ? (uint64_t)-1UL : ((1UL << N) - 1)); +} + +/* result<0> to val<N> */ +static inline uint64_t +pickbit (uint64_t val, int N) +{ + return pickbits64 (val, N, N); +} + +static uint64_t +expand_logical_immediate (uint32_t S, uint32_t R, uint32_t N) +{ + uint64_t mask; + uint64_t imm; + unsigned simd_size; + + /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R + (in other words, right rotated by R), then replicated. */ + if (N != 0) + { + simd_size = 64; + mask = 0xffffffffffffffffull; + } + else + { + switch (S) + { + case 0x00 ... 0x1f: /* 0xxxxx */ simd_size = 32; break; + case 0x20 ... 0x2f: /* 10xxxx */ simd_size = 16; S &= 0xf; break; + case 0x30 ... 0x37: /* 110xxx */ simd_size = 8; S &= 0x7; break; + case 0x38 ... 0x3b: /* 1110xx */ simd_size = 4; S &= 0x3; break; + case 0x3c ... 0x3d: /* 11110x */ simd_size = 2; S &= 0x1; break; + default: return 0; + } + mask = (1ull << simd_size) - 1; + /* Top bits are IGNORED. */ + R &= simd_size - 1; + } + + /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected. */ + if (S == simd_size - 1) + return 0; + + /* S+1 consecutive bits to 1. */ + /* NOTE: S can't be 63 due to detection above. */ + imm = (1ull << (S + 1)) - 1; + + /* Rotate to the left by simd_size - R. */ + if (R != 0) + imm = ((imm << (simd_size - R)) & mask) | (imm >> R); + + /* Replicate the value according to SIMD size. */ + switch (simd_size) + { + case 2: imm = (imm << 2) | imm; + case 4: imm = (imm << 4) | imm; + case 8: imm = (imm << 8) | imm; + case 16: imm = (imm << 16) | imm; + case 32: imm = (imm << 32) | imm; + case 64: break; + default: return 0; + } + + return imm; +} + +/* Instr[22,10] encodes N immr and imms. we want a lookup table + for each possible combination i.e. 13 bits worth of int entries. */ +#define LI_TABLE_SIZE (1 << 13) +static uint64_t LITable[LI_TABLE_SIZE]; + +void +aarch64_init_LIT_table (void) +{ + unsigned index; + + for (index = 0; index < LI_TABLE_SIZE; index++) + { + uint32_t N = uimm (index, 12, 12); + uint32_t immr = uimm (index, 11, 6); + uint32_t imms = uimm (index, 5, 0); + + LITable [index] = expand_logical_immediate (imms, immr, N); + } +} + +static void +dexNotify (sim_cpu *cpu) +{ + /* instr[14,0] == type : 0 ==> method entry, 1 ==> method reentry + 2 ==> exit Java, 3 ==> start next bytecode. */ + uint32_t type = uimm (aarch64_get_instr (cpu), 14, 0); + + TRACE_EVENTS (cpu, "Notify Insn encountered, type = 0x%x", type); + + switch (type) + { + case 0: + /* aarch64_notifyMethodEntry (aarch64_get_reg_u64 (cpu, R23, 0), + aarch64_get_reg_u64 (cpu, R22, 0)); */ + break; + case 1: + /* aarch64_notifyMethodReentry (aarch64_get_reg_u64 (cpu, R23, 0), + aarch64_get_reg_u64 (cpu, R22, 0)); */ + break; + case 2: + /* aarch64_notifyMethodExit (); */ + break; + case 3: + /* aarch64_notifyBCStart (aarch64_get_reg_u64 (cpu, R23, 0), + aarch64_get_reg_u64 (cpu, R22, 0)); */ + break; + } +} + +/* secondary decode within top level groups */ + +static void +dexPseudo (sim_cpu *cpu) +{ + /* assert instr[28,27] = 00 + + We provide 2 pseudo instructions: + + HALT stops execution of the simulator causing an immediate + return to the x86 code which entered it. + + CALLOUT initiates recursive entry into x86 code. A register + argument holds the address of the x86 routine. Immediate + values in the instruction identify the number of general + purpose and floating point register arguments to be passed + and the type of any value to be returned. */ + + uint32_t PSEUDO_HALT = 0xE0000000U; + uint32_t PSEUDO_CALLOUT = 0x00018000U; + uint32_t PSEUDO_CALLOUTR = 0x00018001U; + uint32_t PSEUDO_NOTIFY = 0x00014000U; + uint32_t dispatch; + + if (aarch64_get_instr (cpu) == PSEUDO_HALT) + { + TRACE_EVENTS (cpu, " Pseudo Halt Instruction"); + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), + sim_stopped, SIM_SIGTRAP); + } + + dispatch = uimm (aarch64_get_instr (cpu), 31, 15); + + /* We do not handle callouts at the moment. */ + if (dispatch == PSEUDO_CALLOUT || dispatch == PSEUDO_CALLOUTR) + { + TRACE_EVENTS (cpu, " Callout"); + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), + sim_stopped, SIM_SIGABRT); + } + + else if (dispatch == PSEUDO_NOTIFY) + dexNotify (cpu); + + else + HALT_UNALLOC; +} + +/* Load-store single register (unscaled offset) + These instructions employ a base register plus an unscaled signed + 9 bit offset. + + N.B. the base register (source) can be Xn or SP. all other + registers may not be SP. */ + +/* 32 bit load 32 bit unscaled signed 9 bit. */ +static void +ldur32 (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u32 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + offset)); +} + +/* 64 bit load 64 bit unscaled signed 9 bit. */ +static void +ldur64 (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u64 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + offset)); +} + +/* 32 bit load zero-extended byte unscaled signed 9 bit. */ +static void +ldurb32 (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u8 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + offset)); +} + +/* 32 bit load sign-extended byte unscaled signed 9 bit. */ +static void +ldursb32 (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rt, NO_SP, (uint32_t) aarch64_get_mem_s8 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + offset)); +} + +/* 64 bit load sign-extended byte unscaled signed 9 bit. */ +static void +ldursb64 (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_s64 (cpu, rt, NO_SP, aarch64_get_mem_s8 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + offset)); +} + +/* 32 bit load zero-extended short unscaled signed 9 bit */ +static void +ldurh32 (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_mem_u16 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + offset)); +} + +/* 32 bit load sign-extended short unscaled signed 9 bit */ +static void +ldursh32 (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) aarch64_get_mem_s16 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + offset)); +} + +/* 64 bit load sign-extended short unscaled signed 9 bit */ +static void +ldursh64 (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_s64 (cpu, rt, NO_SP, aarch64_get_mem_s16 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + offset)); +} + +/* 64 bit load sign-extended word unscaled signed 9 bit */ +static void +ldursw (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) aarch64_get_mem_s32 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + offset)); +} + +/* N.B. with stores the value in source is written to the address + identified by source2 modified by offset. */ + +/* 32 bit store 32 bit unscaled signed 9 bit. */ +static void +stur32 (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_mem_u32 (cpu, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset, + aarch64_get_reg_u32 (cpu, rd, NO_SP)); +} + +/* 64 bit store 64 bit unscaled signed 9 bit */ +static void +stur64 (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_mem_u64 (cpu, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset, + aarch64_get_reg_u64 (cpu, rd, NO_SP)); +} + +/* 32 bit store byte unscaled signed 9 bit */ +static void +sturb (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_mem_u8 (cpu, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset, + aarch64_get_reg_u8 (cpu, rd, NO_SP)); +} + +/* 32 bit store short unscaled signed 9 bit */ +static void +sturh (sim_cpu *cpu, int32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_mem_u16 (cpu, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset, + aarch64_get_reg_u16 (cpu, rd, NO_SP)); +} + +/* Load single register pc-relative label + Offset is a signed 19 bit immediate count in words + rt may not be SP. */ + +/* 32 bit pc-relative load */ +static void +ldr32_pcrel (sim_cpu *cpu, int32_t offset) +{ + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_mem_u32 + (cpu, aarch64_get_PC (cpu) + offset * 4)); +} + +/* 64 bit pc-relative load */ +static void +ldr_pcrel (sim_cpu *cpu, int32_t offset) +{ + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_mem_u64 + (cpu, aarch64_get_PC (cpu) + offset * 4)); +} + +/* sign extended 32 bit pc-relative load */ +static void +ldrsw_pcrel (sim_cpu *cpu, int32_t offset) +{ + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_mem_s32 + (cpu, aarch64_get_PC (cpu) + offset * 4)); +} + +/* float pc-relative load */ +static void +fldrs_pcrel (sim_cpu *cpu, int32_t offset) +{ + unsigned int rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, rd, + aarch64_get_mem_float + (cpu, aarch64_get_PC (cpu) + offset * 4)); +} + +/* double pc-relative load */ +static void +fldrd_pcrel (sim_cpu *cpu, int32_t offset) +{ + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, st, + aarch64_get_mem_double + (cpu, aarch64_get_PC (cpu) + offset * 4)); +} + +/* long double pc-relative load. */ +static void +fldrq_pcrel (sim_cpu *cpu, int32_t offset) +{ + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t addr = aarch64_get_PC (cpu) + offset * 4; + FRegister a; + + aarch64_get_mem_long_double (cpu, addr, & a); + aarch64_set_FP_long_double (cpu, st, a); +} + +/* This can be used to scale an offset by applying + the requisite shift. the second argument is either + 16, 32 or 64. */ + +#define SCALE(_offset, _elementSize) \ + ((_offset) << ScaleShift ## _elementSize) + +/* This can be used to optionally scale a register derived offset + by applying the requisite shift as indicated by the Scaling + argument. the second argument is either Byte, Short, Word + or Long. The third argument is either Scaled or Unscaled. + N.B. when _Scaling is Scaled the shift gets ANDed with + all 1s while when it is Unscaled it gets ANDed with 0. */ + +#define OPT_SCALE(_offset, _elementType, _Scaling) \ + ((_offset) << (_Scaling ? ScaleShift ## _elementType : 0)) + +/* This can be used to zero or sign extend a 32 bit register derived + value to a 64 bit value. the first argument must be the value as + a uint32_t and the second must be either UXTW or SXTW. The result + is returned as an int64_t. */ + +static inline int64_t +extend (uint32_t value, Extension extension) +{ + union + { + uint32_t u; + int32_t n; + } x; + + /* A branchless variant of this ought to be possible. */ + if (extension == UXTW || extension == NoExtension) + return value; + + x.u = value; + return x.n; +} + +/* Scalar Floating Point + + FP load/store single register (4 addressing modes) + + N.B. the base register (source) can be the stack pointer. + The secondary source register (source2) can only be an Xn register. */ + +/* Load 32 bit unscaled signed 9 bit with pre- or post-writeback. */ +static void +fldrs_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_FP_float (cpu, st, aarch64_get_mem_float (cpu, address)); + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* Load 32 bit scaled unsigned 12 bit. */ +static void +fldrs_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + + aarch64_set_FP_float (cpu, st, + aarch64_get_mem_float + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + SCALE (offset, 32))); +} + +/* Load 32 bit scaled or unscaled zero- or sign-extended + 32-bit register offset. */ +static void +fldrs_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension); + uint64_t displacement = OPT_SCALE (extended, 32, scaling); + + aarch64_set_FP_float (cpu, st, + aarch64_get_mem_float + (cpu, address + displacement)); +} + +/* Load 64 bit unscaled signed 9 bit with pre- or post-writeback. */ +static void +fldrd_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_FP_double (cpu, st, aarch64_get_mem_double (cpu, address)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* Load 64 bit scaled unsigned 12 bit. */ +static void +fldrd_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 64); + + aarch64_set_FP_double (cpu, st, aarch64_get_mem_double (cpu, address)); +} + +/* Load 64 bit scaled or unscaled zero- or sign-extended 32-bit register offset. */ +static void +fldrd_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension); + uint64_t displacement = OPT_SCALE (extended, 64, scaling); + + fldrd_wb (cpu, displacement, NoWriteBack); +} + +/* Load 128 bit unscaled signed 9 bit with pre- or post-writeback. */ +static void +fldrq_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + FRegister a; + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_get_mem_long_double (cpu, address, & a); + aarch64_set_FP_long_double (cpu, st, a); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* Load 128 bit scaled unsigned 12 bit. */ +static void +fldrq_abs (sim_cpu *cpu, uint32_t offset) +{ + FRegister a; + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 128); + + aarch64_get_mem_long_double (cpu, address, & a); + aarch64_set_FP_long_double (cpu, st, a); +} + +/* Load 128 bit scaled or unscaled zero- or sign-extended 32-bit register offset */ +static void +fldrq_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension); + uint64_t displacement = OPT_SCALE (extended, 128, scaling); + + fldrq_wb (cpu, displacement, NoWriteBack); +} + +/* Memory Access + + load-store single register + There are four addressing modes available here which all employ a + 64 bit source (base) register. + + N.B. the base register (source) can be the stack pointer. + The secondary source register (source2)can only be an Xn register. + + Scaled, 12-bit, unsigned immediate offset, without pre- and + post-index options. + Unscaled, 9-bit, signed immediate offset with pre- or post-index + writeback. + scaled or unscaled 64-bit register offset. + scaled or unscaled 32-bit extended register offset. + + All offsets are assumed to be raw from the decode i.e. the + simulator is expected to adjust scaled offsets based on the + accessed data size with register or extended register offset + versions the same applies except that in the latter case the + operation may also require a sign extend. + + A separate method is provided for each possible addressing mode. */ + +/* 32 bit load 32 bit scaled unsigned 12 bit */ +static void +ldr32_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + /* The target register may not be SP but the source may be. */ + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u32 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + SCALE (offset, 32))); +} + +/* 32 bit load 32 bit unscaled signed 9 bit with pre- or post-writeback. */ +static void +ldr32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address; + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u32 (cpu, address)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 32 bit load 32 bit scaled or unscaled + zero- or sign-extended 32-bit register offset */ +static void +ldr32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + /* rn may reference SP, rm and rt must reference ZR */ + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension); + uint64_t displacement = OPT_SCALE (extended, 32, scaling); + + aarch64_set_reg_u64 (cpu, rt, NO_SP, + aarch64_get_mem_u32 (cpu, address + displacement)); +} + +/* 64 bit load 64 bit scaled unsigned 12 bit */ +static void +ldr_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + /* The target register may not be SP but the source may be. */ + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u64 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + SCALE (offset, 64))); +} + +/* 64 bit load 64 bit unscaled signed 9 bit with pre- or post-writeback. */ +static void +ldr_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address; + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u64 (cpu, address)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 64 bit load 64 bit scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +ldr_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + /* rn may reference SP, rm and rt must reference ZR */ + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension); + uint64_t displacement = OPT_SCALE (extended, 64, scaling); + + aarch64_set_reg_u64 (cpu, rt, NO_SP, + aarch64_get_mem_u64 (cpu, address + displacement)); +} + +/* 32 bit load zero-extended byte scaled unsigned 12 bit. */ +static void +ldrb32_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + /* The target register may not be SP but the source may be + there is no scaling required for a byte load. */ + aarch64_set_reg_u64 (cpu, rt, NO_SP, + aarch64_get_mem_u8 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset)); +} + +/* 32 bit load zero-extended byte unscaled signed 9 bit with pre- or post-writeback. */ +static void +ldrb32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address; + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u8 (cpu, address)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 32 bit load zero-extended byte scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +ldrb32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + /* rn may reference SP, rm and rt must reference ZR */ + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t displacement = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), + extension); + + /* There is no scaling required for a byte load. */ + aarch64_set_reg_u64 (cpu, rt, NO_SP, + aarch64_get_mem_u8 (cpu, address + displacement)); +} + +/* 64 bit load sign-extended byte unscaled signed 9 bit + with pre- or post-writeback. */ +static void +ldrsb_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address; + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_s8 (cpu, address)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 64 bit load sign-extended byte scaled unsigned 12 bit. */ +static void +ldrsb_abs (sim_cpu *cpu, uint32_t offset) +{ + ldrsb_wb (cpu, offset, NoWriteBack); +} + +/* 64 bit load sign-extended byte scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +ldrsb_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + /* rn may reference SP, rm and rt must reference ZR */ + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t displacement = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), + extension); + /* There is no scaling required for a byte load. */ + aarch64_set_reg_u64 (cpu, rt, NO_SP, + aarch64_get_mem_s8 (cpu, address + displacement)); +} + +/* 32 bit load zero-extended short scaled unsigned 12 bit. */ +static void +ldrh32_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + /* The target register may not be SP but the source may be. */ + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u16 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + SCALE (offset, 16))); +} + +/* 32 bit load zero-extended short unscaled signed 9 bit + with pre- or post-writeback. */ +static void +ldrh32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address; + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u16 (cpu, address)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 32 bit load zero-extended short scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +ldrh32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + /* rn may reference SP, rm and rt must reference ZR */ + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension); + uint64_t displacement = OPT_SCALE (extended, 16, scaling); + + aarch64_set_reg_u64 (cpu, rt, NO_SP, + aarch64_get_mem_u16 (cpu, address + displacement)); +} + +/* 32 bit load sign-extended short scaled unsigned 12 bit. */ +static void +ldrsh32_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + /* The target register may not be SP but the source may be. */ + aarch64_set_reg_u64 (cpu, rt, NO_SP, (uint32_t) aarch64_get_mem_s16 + (cpu, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + + SCALE (offset, 16))); +} + +/* 32 bit load sign-extended short unscaled signed 9 bit + with pre- or post-writeback. */ +static void +ldrsh32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address; + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_reg_u64 (cpu, rt, NO_SP, + (uint32_t) aarch64_get_mem_s16 (cpu, address)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 32 bit load sign-extended short scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +ldrsh32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + /* rn may reference SP, rm and rt must reference ZR */ + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension); + uint64_t displacement = OPT_SCALE (extended, 16, scaling); + + aarch64_set_reg_u64 (cpu, rt, NO_SP, + (uint32_t) aarch64_get_mem_s16 + (cpu, address + displacement)); +} + +/* 64 bit load sign-extended short scaled unsigned 12 bit. */ +static void +ldrsh_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + /* The target register may not be SP but the source may be. */ + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_s16 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + SCALE (offset, 16))); +} + +/* 64 bit load sign-extended short unscaled signed 9 bit + with pre- or post-writeback. */ +static void +ldrsh64_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address; + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_s16 (cpu, address)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 64 bit load sign-extended short scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +ldrsh_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + /* rn may reference SP, rm and rt must reference ZR */ + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension); + uint64_t displacement = OPT_SCALE (extended, 16, scaling); + + aarch64_set_reg_u64 (cpu, rt, NO_SP, + aarch64_get_mem_s16 (cpu, address + displacement)); +} + +/* 64 bit load sign-extended 32 bit scaled unsigned 12 bit. */ +static void +ldrsw_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + /* The target register may not be SP but the source may be. */ + return aarch64_set_reg_s64 (cpu, rt, NO_SP, aarch64_get_mem_s32 + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + SCALE (offset, 32))); +} + +/* 64 bit load sign-extended 32 bit unscaled signed 9 bit + with pre- or post-writeback. */ +static void +ldrsw_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address; + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_reg_s64 (cpu, rt, NO_SP, aarch64_get_mem_s32 (cpu, address)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 64 bit load sign-extended 32 bit scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +ldrsw_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + /* rn may reference SP, rm and rt must reference ZR */ + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension); + uint64_t displacement = OPT_SCALE (extended, 32, scaling); + + aarch64_set_reg_s64 (cpu, rt, NO_SP, + aarch64_get_mem_s32 (cpu, address + displacement)); +} + +/* N.B. with stores the value in source is written to the + address identified by source2 modified by source3/offset. */ + +/* 32 bit store scaled unsigned 12 bit. */ +static void +str32_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + /* The target register may not be SP but the source may be. */ + aarch64_set_mem_u32 (cpu, (aarch64_get_reg_u64 (cpu, rn, SP_OK) + + SCALE (offset, 32)), + aarch64_get_reg_u32 (cpu, rt, NO_SP)); +} + +/* 32 bit store unscaled signed 9 bit with pre- or post-writeback. */ +static void +str32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address; + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + if (wb != Post) + address += offset; + + aarch64_set_mem_u32 (cpu, address, aarch64_get_reg_u32 (cpu, rt, NO_SP)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 32 bit store scaled or unscaled zero- or + sign-extended 32-bit register offset. */ +static void +str32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension); + uint64_t displacement = OPT_SCALE (extended, 32, scaling); + + aarch64_set_mem_u32 (cpu, address + displacement, + aarch64_get_reg_u64 (cpu, rt, NO_SP)); +} + +/* 64 bit store scaled unsigned 12 bit. */ +static void +str_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_mem_u64 (cpu, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + + SCALE (offset, 64), + aarch64_get_reg_u64 (cpu, rt, NO_SP)); +} + +/* 64 bit store unscaled signed 9 bit with pre- or post-writeback. */ +static void +str_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address; + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_mem_u64 (cpu, address, aarch64_get_reg_u64 (cpu, rt, NO_SP)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 64 bit store scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +str_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + /* rn may reference SP, rm and rt must reference ZR */ + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), + extension); + uint64_t displacement = OPT_SCALE (extended, 64, scaling); + + aarch64_set_mem_u64 (cpu, address + displacement, + aarch64_get_reg_u64 (cpu, rt, NO_SP)); +} + +/* 32 bit store byte scaled unsigned 12 bit. */ +static void +strb_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + /* The target register may not be SP but the source may be. + There is no scaling required for a byte load. */ + aarch64_set_mem_u8 (cpu, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset, + aarch64_get_reg_u8 (cpu, rt, NO_SP)); +} + +/* 32 bit store byte unscaled signed 9 bit with pre- or post-writeback. */ +static void +strb_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address; + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_mem_u8 (cpu, address, aarch64_get_reg_u8 (cpu, rt, NO_SP)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 32 bit store byte scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +strb_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + /* rn may reference SP, rm and rt must reference ZR */ + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t displacement = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), + extension); + + /* There is no scaling required for a byte load. */ + aarch64_set_mem_u8 (cpu, address + displacement, + aarch64_get_reg_u8 (cpu, rt, NO_SP)); +} + +/* 32 bit store short scaled unsigned 12 bit. */ +static void +strh_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + /* The target register may not be SP but the source may be. */ + aarch64_set_mem_u16 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + + SCALE (offset, 16), + aarch64_get_reg_u16 (cpu, rt, NO_SP)); +} + +/* 32 bit store short unscaled signed 9 bit with pre- or post-writeback. */ +static void +strh_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address; + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_mem_u16 (cpu, address, aarch64_get_reg_u16 (cpu, rt, NO_SP)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 32 bit store short scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +strh_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + /* rn may reference SP, rm and rt must reference ZR */ + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), extension); + uint64_t displacement = OPT_SCALE (extended, 16, scaling); + + aarch64_set_mem_u16 (cpu, address + displacement, + aarch64_get_reg_u16 (cpu, rt, NO_SP)); +} + +/* Prefetch unsigned 12 bit. */ +static void +prfm_abs (sim_cpu *cpu, uint32_t offset) +{ + /* instr[4,0] = prfop : 00000 ==> PLDL1KEEP, 00001 ==> PLDL1STRM, + 00010 ==> PLDL2KEEP, 00001 ==> PLDL2STRM, + 00100 ==> PLDL3KEEP, 00101 ==> PLDL3STRM, + 10000 ==> PSTL1KEEP, 10001 ==> PSTL1STRM, + 10010 ==> PSTL2KEEP, 10001 ==> PSTL2STRM, + 10100 ==> PSTL3KEEP, 10101 ==> PSTL3STRM, + ow ==> UNALLOC + PrfOp prfop = prfop (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK) + + SCALE (offset, 64). */ + + /* TODO : implement prefetch of address. */ +} + +/* Prefetch scaled or unscaled zero- or sign-extended 32-bit register offset. */ +static void +prfm_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + /* instr[4,0] = prfop : 00000 ==> PLDL1KEEP, 00001 ==> PLDL1STRM, + 00010 ==> PLDL2KEEP, 00001 ==> PLDL2STRM, + 00100 ==> PLDL3KEEP, 00101 ==> PLDL3STRM, + 10000 ==> PSTL1KEEP, 10001 ==> PSTL1STRM, + 10010 ==> PSTL2KEEP, 10001 ==> PSTL2STRM, + 10100 ==> PSTL3KEEP, 10101 ==> PSTL3STRM, + ow ==> UNALLOC + rn may reference SP, rm may only reference ZR + PrfOp prfop = prfop (aarch64_get_instr (cpu), 4, 0); + uint64_t base = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), + extension); + uint64_t displacement = OPT_SCALE (extended, 64, scaling); + uint64_t address = base + displacement. */ + + /* TODO : implement prefetch of address */ +} + +/* 64 bit pc-relative prefetch. */ +static void +prfm_pcrel (sim_cpu *cpu, int32_t offset) +{ + /* instr[4,0] = prfop : 00000 ==> PLDL1KEEP, 00001 ==> PLDL1STRM, + 00010 ==> PLDL2KEEP, 00001 ==> PLDL2STRM, + 00100 ==> PLDL3KEEP, 00101 ==> PLDL3STRM, + 10000 ==> PSTL1KEEP, 10001 ==> PSTL1STRM, + 10010 ==> PSTL2KEEP, 10001 ==> PSTL2STRM, + 10100 ==> PSTL3KEEP, 10101 ==> PSTL3STRM, + ow ==> UNALLOC + PrfOp prfop = prfop (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_PC (cpu) + offset. */ + + /* TODO : implement this */ +} + +/* Load-store exclusive. */ + +static void +ldxr (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int size = uimm (aarch64_get_instr (cpu), 31, 30); + /* int ordered = uimm (aarch64_get_instr (cpu), 15, 15); */ + /* int exclusive = ! uimm (aarch64_get_instr (cpu), 23, 23); */ + + switch (size) + { + case 0: + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u8 (cpu, address)); + break; + case 1: + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u16 (cpu, address)); + break; + case 2: + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u32 (cpu, address)); + break; + case 3: + aarch64_set_reg_u64 (cpu, rt, NO_SP, aarch64_get_mem_u64 (cpu, address)); + break; + default: + HALT_UNALLOC; + } +} + +static void +stxr (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned rs = uimm (aarch64_get_instr (cpu), 20, 16); + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int size = uimm (aarch64_get_instr (cpu), 31, 30); + uint64_t data = aarch64_get_reg_u64 (cpu, rt, NO_SP); + + switch (size) + { + case 0: aarch64_set_mem_u8 (cpu, address, data); break; + case 1: aarch64_set_mem_u16 (cpu, address, data); break; + case 2: aarch64_set_mem_u32 (cpu, address, data); break; + case 3: aarch64_set_mem_u64 (cpu, address, data); break; + default: HALT_UNALLOC; + } + + aarch64_set_reg_u64 (cpu, rs, NO_SP, 0); /* Always exclusive... */ +} + +static void +dexLoadLiteral (sim_cpu *cpu) +{ + /* instr[29,27] == 011 + instr[25,24] == 00 + instr[31,30:26] = opc: 000 ==> LDRW, 001 ==> FLDRS + 010 ==> LDRX, 011 ==> FLDRD + 100 ==> LDRSW, 101 ==> FLDRQ + 110 ==> PRFM, 111 ==> UNALLOC + instr[26] ==> V : 0 ==> GReg, 1 ==> FReg + instr[23, 5] == simm19 */ + + /* unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); */ + uint32_t dispatch = ( (uimm (aarch64_get_instr (cpu), 31, 30) << 1) + | uimm (aarch64_get_instr (cpu), 26, 26)); + int32_t imm = simm32 (aarch64_get_instr (cpu), 23, 5); + + switch (dispatch) + { + case 0: ldr32_pcrel (cpu, imm); break; + case 1: fldrs_pcrel (cpu, imm); break; + case 2: ldr_pcrel (cpu, imm); break; + case 3: fldrd_pcrel (cpu, imm); break; + case 4: ldrsw_pcrel (cpu, imm); break; + case 5: fldrq_pcrel (cpu, imm); break; + case 6: prfm_pcrel (cpu, imm); break; + case 7: + default: + HALT_UNALLOC; + } +} + +/* Immediate arithmetic + The aimm argument is a 12 bit unsigned value or a 12 bit unsigned + value left shifted by 12 bits (done at decode). + + N.B. the register args (dest, source) can normally be Xn or SP. + the exception occurs for flag setting instructions which may + only use Xn for the output (dest). */ + +/* 32 bit add immediate. */ +static void +add32 (sim_cpu *cpu, uint32_t aimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u32 (cpu, rn, SP_OK) + aimm); +} + +/* 64 bit add immediate. */ +static void +add64 (sim_cpu *cpu, uint32_t aimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + aimm); +} + +static void +set_flags_for_add32 (sim_cpu *cpu, int32_t value1, int32_t value2) +{ + int32_t result = value1 + value2; + int64_t sresult = (int64_t) value1 + (int64_t) value2; + uint64_t uresult = (uint64_t)(uint32_t) value1 + + (uint64_t)(uint32_t) value2; + uint32_t flags = 0; + + if (result == 0) + flags |= Z; + + if (result & (1 << 31)) + flags |= N; + + if (uresult != result) + flags |= C; + + if (sresult != result) + flags |= V; + + aarch64_set_CPSR (cpu, flags); +} + +static void +set_flags_for_add64 (sim_cpu *cpu, uint64_t value1, uint64_t value2) +{ + int64_t sval1 = value1; + int64_t sval2 = value2; + uint64_t result = value1 + value2; + int64_t sresult = sval1 + sval2; + uint32_t flags = 0; + + if (result == 0) + flags |= Z; + + if (result & (1ULL << 63)) + flags |= N; + + if (sval1 < 0) + { + if (sval2 < 0) + { + /* Negative plus a negative. Overflow happens if + the result is greater than either of the operands. */ + if (sresult > sval1 || sresult > sval2) + flags |= V; + } + /* else Negative plus a positive. Overflow cannot happen. */ + } + else /* value1 is +ve. */ + { + if (sval2 < 0) + { + /* Overflow can only occur if we computed "0 - MININT". */ + if (sval1 == 0 && sval2 == (1LL << 63)) + flags |= V; + } + else + { + /* Postive plus positive - overflow has happened if the + result is smaller than either of the operands. */ + if (result < value1 || result < value2) + flags |= V | C; + } + } + + aarch64_set_CPSR (cpu, flags); +} + +#define NEG(a) (((a) & signbit) == signbit) +#define POS(a) (((a) & signbit) == 0) + +static void +set_flags_for_sub32 (sim_cpu *cpu, uint32_t value1, uint32_t value2) +{ + uint32_t result = value1 - value2; + uint32_t flags = 0; + uint32_t signbit = 1ULL << 31; + + if (result == 0) + flags |= Z; + + if (NEG (result)) + flags |= N; + + if ( (NEG (value1) && POS (value2)) + || (NEG (value1) && POS (result)) + || (POS (value2) && POS (result))) + flags |= C; + + if ( (NEG (value1) && POS (value2) && POS (result)) + || (POS (value1) && NEG (value2) && NEG (result))) + flags |= V; + + aarch64_set_CPSR (cpu, flags); +} + +static void +set_flags_for_sub64 (sim_cpu *cpu, uint64_t value1, uint64_t value2) +{ + uint64_t result = value1 - value2; + uint32_t flags = 0; + uint64_t signbit = 1ULL << 63; + + if (result == 0) + flags |= Z; + + if (NEG (result)) + flags |= N; + + if ( (NEG (value1) && POS (value2)) + || (NEG (value1) && POS (result)) + || (POS (value2) && POS (result))) + flags |= C; + + if ( (NEG (value1) && POS (value2) && POS (result)) + || (POS (value1) && NEG (value2) && NEG (result))) + flags |= V; + + aarch64_set_CPSR (cpu, flags); +} + +static void +set_flags_for_binop32 (sim_cpu *cpu, uint32_t result) +{ + uint32_t flags = 0; + + if (result == 0) + flags |= Z; + else + flags &= ~ Z; + + if (result & (1 << 31)) + flags |= N; + else + flags &= ~ N; + + aarch64_set_CPSR (cpu, flags); +} + +static void +set_flags_for_binop64 (sim_cpu *cpu, uint64_t result) +{ + uint32_t flags = 0; + + if (result == 0) + flags |= Z; + else + flags &= ~ Z; + + if (result & (1ULL << 63)) + flags |= N; + else + flags &= ~ N; + + aarch64_set_CPSR (cpu, flags); +} + +/* 32 bit add immediate set flags. */ +static void +adds32 (sim_cpu *cpu, uint32_t aimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + /* TODO : do we need to worry about signs here? */ + int32_t value1 = aarch64_get_reg_s32 (cpu, rn, SP_OK); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + aimm); + set_flags_for_add32 (cpu, value1, aimm); +} + +/* 64 bit add immediate set flags. */ +static void +adds64 (sim_cpu *cpu, uint32_t aimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK); + uint64_t value2 = aimm; + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2); + set_flags_for_add64 (cpu, value1, value2); +} + +/* 32 bit sub immediate. */ +static void +sub32 (sim_cpu *cpu, uint32_t aimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u32 (cpu, rn, SP_OK) - aimm); +} + +/* 64 bit sub immediate. */ +static void +sub64 (sim_cpu *cpu, uint32_t aimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u64 (cpu, rn, SP_OK) - aimm); +} + +/* 32 bit sub immediate set flags. */ +static void +subs32 (sim_cpu *cpu, uint32_t aimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint32_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK); + uint32_t value2 = aimm; + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2); + set_flags_for_sub32 (cpu, value1, value2); +} + +/* 64 bit sub immediate set flags. */ +static void +subs64 (sim_cpu *cpu, uint32_t aimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK); + uint32_t value2 = aimm; + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2); + set_flags_for_sub64 (cpu, value1, value2); +} + +/* Data Processing Register. */ + +/* First two helpers to perform the shift operations. */ + +static inline uint32_t +shifted32 (uint32_t value, Shift shift, uint32_t count) +{ + switch (shift) + { + default: + case LSL: + return (value << count); + case LSR: + return (value >> count); + case ASR: + { + int32_t svalue = value; + return (svalue >> count); + } + case ROR: + { + uint32_t top = value >> count; + uint32_t bottom = value << (32 - count); + return (bottom | top); + } + } +} + +static inline uint64_t +shifted64 (uint64_t value, Shift shift, uint32_t count) +{ + switch (shift) + { + default: + case LSL: + return (value << count); + case LSR: + return (value >> count); + case ASR: + { + int64_t svalue = value; + return (svalue >> count); + } + case ROR: + { + uint64_t top = value >> count; + uint64_t bottom = value << (64 - count); + return (bottom | top); + } + } +} + +/* Arithmetic shifted register. + These allow an optional LSL, ASR or LSR to the second source + register with a count up to the register bit count. + + N.B register args may not be SP. */ + +/* 32 bit ADD shifted register. */ +static void +add32_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_reg_u32 (cpu, rn, NO_SP) + + shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), + shift, count)); +} + +/* 64 bit ADD shifted register. */ +static void +add64_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_reg_u64 (cpu, rn, NO_SP) + + shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), + shift, count)); +} + +/* 32 bit ADD shifted register setting flags. */ +static void +adds32_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP); + uint32_t value2 = shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), + shift, count); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2); + set_flags_for_add32 (cpu, value1, value2); +} + +/* 64 bit ADD shifted register setting flags. */ +static void +adds64_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP); + uint64_t value2 = shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), + shift, count); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2); + set_flags_for_add64 (cpu, value1, value2); +} + +/* 32 bit SUB shifted register. */ +static void +sub32_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_reg_u32 (cpu, rn, NO_SP) + - shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), + shift, count)); +} + +/* 64 bit SUB shifted register. */ +static void +sub64_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_reg_u64 (cpu, rn, NO_SP) + - shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), + shift, count)); +} + +/* 32 bit SUB shifted register setting flags. */ +static void +subs32_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP); + uint32_t value2 = shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), + shift, count); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2); + set_flags_for_sub32 (cpu, value1, value2); +} + +/* 64 bit SUB shifted register setting flags. */ +static void +subs64_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP); + uint64_t value2 = shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), + shift, count); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2); + set_flags_for_sub64 (cpu, value1, value2); +} + +/* First a couple more helpers to fetch the + relevant source register element either + sign or zero extended as required by the + extension value. */ + +static uint32_t +extreg32 (sim_cpu *cpu, unsigned int lo, Extension extension) +{ + switch (extension) + { + case UXTB: return aarch64_get_reg_u8 (cpu, lo, NO_SP); + case UXTH: return aarch64_get_reg_u16 (cpu, lo, NO_SP); + case UXTW: /* Fall through. */ + case UXTX: return aarch64_get_reg_u32 (cpu, lo, NO_SP); + case SXTB: return aarch64_get_reg_s8 (cpu, lo, NO_SP); + case SXTH: return aarch64_get_reg_s16 (cpu, lo, NO_SP); + case SXTW: /* Fall through. */ + case SXTX: /* Fall through. */ + default: return aarch64_get_reg_s32 (cpu, lo, NO_SP); + } +} + +static uint64_t +extreg64 (sim_cpu *cpu, unsigned int lo, Extension extension) +{ + switch (extension) + { + case UXTB: return aarch64_get_reg_u8 (cpu, lo, NO_SP); + case UXTH: return aarch64_get_reg_u16 (cpu, lo, NO_SP); + case UXTW: return aarch64_get_reg_u32 (cpu, lo, NO_SP); + case UXTX: return aarch64_get_reg_u64 (cpu, lo, NO_SP); + case SXTB: return aarch64_get_reg_s8 (cpu, lo, NO_SP); + case SXTH: return aarch64_get_reg_s16 (cpu, lo, NO_SP); + case SXTW: return aarch64_get_reg_s32 (cpu, lo, NO_SP); + case SXTX: + default: return aarch64_get_reg_s64 (cpu, lo, NO_SP); + } +} + +/* Arithmetic extending register + These allow an optional sign extension of some portion of the + second source register followed by an optional left shift of + between 1 and 4 bits (i.e. a shift of 0-4 bits???) + + N.B output (dest) and first input arg (source) may normally be Xn + or SP. However, for flag setting operations dest can only be + Xn. Second input registers are always Xn. */ + +/* 32 bit ADD extending register. */ +static void +add32_ext (sim_cpu *cpu, Extension extension, uint32_t shift) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u32 (cpu, rn, SP_OK) + + (extreg32 (cpu, rm, extension) << shift)); +} + +/* 64 bit ADD extending register. + N.B. This subsumes the case with 64 bit source2 and UXTX #n or LSL #0. */ +static void +add64_ext (sim_cpu *cpu, Extension extension, uint32_t shift) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + + (extreg64 (cpu, rm, extension) << shift)); +} + +/* 32 bit ADD extending register setting flags. */ +static void +adds32_ext (sim_cpu *cpu, Extension extension, uint32_t shift) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, SP_OK); + uint32_t value2 = extreg32 (cpu, rm, extension) << shift; + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2); + set_flags_for_add32 (cpu, value1, value2); +} + +/* 64 bit ADD extending register setting flags */ +/* N.B. this subsumes the case with 64 bit source2 and UXTX #n or LSL #0 */ +static void +adds64_ext (sim_cpu *cpu, Extension extension, uint32_t shift) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK); + uint64_t value2 = extreg64 (cpu, rm, extension) << shift; + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2); + set_flags_for_add64 (cpu, value1, value2); +} + +/* 32 bit SUB extending register. */ +static void +sub32_ext (sim_cpu *cpu, Extension extension, uint32_t shift) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u32 (cpu, rn, SP_OK) + - (extreg32 (cpu, rm, extension) << shift)); +} + +/* 64 bit SUB extending register. */ +/* N.B. this subsumes the case with 64 bit source2 and UXTX #n or LSL #0. */ +static void +sub64_ext (sim_cpu *cpu, Extension extension, uint32_t shift) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + - (extreg64 (cpu, rm, extension) << shift)); +} + +/* 32 bit SUB extending register setting flags. */ +static void +subs32_ext (sim_cpu *cpu, Extension extension, uint32_t shift) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, SP_OK); + uint32_t value2 = extreg32 (cpu, rm, extension) << shift; + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2); + set_flags_for_sub32 (cpu, value1, value2); +} + +/* 64 bit SUB extending register setting flags */ +/* N.B. this subsumes the case with 64 bit source2 and UXTX #n or LSL #0 */ +static void +subs64_ext (sim_cpu *cpu, Extension extension, uint32_t shift) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, SP_OK); + uint64_t value2 = extreg64 (cpu, rm, extension) << shift; + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 - value2); + set_flags_for_sub64 (cpu, value1, value2); +} + +static void +dexAddSubtractImmediate (sim_cpu *cpu) +{ + /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[30] = op : 0 ==> ADD, 1 ==> SUB + instr[29] = set : 0 ==> no flags, 1 ==> set flags + instr[28,24] = 10001 + instr[23,22] = shift : 00 == LSL#0, 01 = LSL#12 1x = UNALLOC + instr[21,10] = uimm12 + instr[9,5] = Rn + instr[4,0] = Rd */ + + /* N.B. the shift is applied at decode before calling the add/sub routine. */ + uint32_t shift = uimm (aarch64_get_instr (cpu), 23, 22); + uint32_t imm = uimm (aarch64_get_instr (cpu), 21, 10); + uint32_t dispatch = uimm (aarch64_get_instr (cpu), 31, 29); + + NYI_assert (28, 24, 0x11); + + if (shift > 1) + HALT_UNALLOC; + + if (shift) + imm <<= 12; + + switch (dispatch) + { + case 0: add32 (cpu, imm); break; + case 1: adds32 (cpu, imm); break; + case 2: sub32 (cpu, imm); break; + case 3: subs32 (cpu, imm); break; + case 4: add64 (cpu, imm); break; + case 5: adds64 (cpu, imm); break; + case 6: sub64 (cpu, imm); break; + case 7: subs64 (cpu, imm); break; + default: + HALT_UNALLOC; + } +} + +static void +dexAddSubtractShiftedRegister (sim_cpu *cpu) +{ + /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[30,29] = op : 00 ==> ADD, 01 ==> ADDS, 10 ==> SUB, 11 ==> SUBS + instr[28,24] = 01011 + instr[23,22] = shift : 0 ==> LSL, 1 ==> LSR, 2 ==> ASR, 3 ==> UNALLOC + instr[21] = 0 + instr[20,16] = Rm + instr[15,10] = count : must be 0xxxxx for 32 bit + instr[9,5] = Rn + instr[4,0] = Rd */ + + uint32_t size = uimm (aarch64_get_instr (cpu), 31, 31); + /* 32 bit operations must have count[5] = 0 + or else we have an UNALLOC. */ + uint32_t count = uimm (aarch64_get_instr (cpu), 15, 10); + /* Shift encoded as ROR is unallocated. */ + Shift shiftType = shift (aarch64_get_instr (cpu), 22); + /* Dispatch on size:op i.e aarch64_get_instr (cpu)[31,29]. */ + uint32_t dispatch = uimm (aarch64_get_instr (cpu), 31, 29); + + NYI_assert (28, 24, 0x0B); + NYI_assert (21, 21, 0); + + if (shiftType == ROR) + HALT_UNALLOC; + + if (!size && uimm (count, 5, 5)) + HALT_UNALLOC; + + switch (dispatch) + { + case 0: add32_shift (cpu, shiftType, count); break; + case 1: adds32_shift (cpu, shiftType, count); break; + case 2: sub32_shift (cpu, shiftType, count); break; + case 3: subs32_shift (cpu, shiftType, count); break; + case 4: add64_shift (cpu, shiftType, count); break; + case 5: adds64_shift (cpu, shiftType, count); break; + case 6: sub64_shift (cpu, shiftType, count); break; + case 7: subs64_shift (cpu, shiftType, count); break; + default: + HALT_UNALLOC; + } +} + +static void +dexAddSubtractExtendedRegister (sim_cpu *cpu) +{ + /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[30] = op : 0 ==> ADD, 1 ==> SUB + instr[29] = set? : 0 ==> no flags, 1 ==> set flags + instr[28,24] = 01011 + instr[23,22] = opt : 0 ==> ok, 1,2,3 ==> UNALLOC + instr[21] = 1 + instr[20,16] = Rm + instr[15,13] = option : 000 ==> UXTB, 001 ==> UXTH, + 000 ==> LSL|UXTW, 001 ==> UXTZ, + 000 ==> SXTB, 001 ==> SXTH, + 000 ==> SXTW, 001 ==> SXTX, + instr[12,10] = shift : 0,1,2,3,4 ==> ok, 5,6,7 ==> UNALLOC + instr[9,5] = Rn + instr[4,0] = Rd */ + + Extension extensionType = extension (aarch64_get_instr (cpu), 13); + uint32_t shift = uimm (aarch64_get_instr (cpu), 12, 10); + /* dispatch on size:op:set? i.e aarch64_get_instr (cpu)[31,29] */ + uint32_t dispatch = uimm (aarch64_get_instr (cpu), 31, 29); + + NYI_assert (28, 24, 0x0B); + NYI_assert (21, 21, 1); + + /* Shift may not exceed 4. */ + if (shift > 4) + HALT_UNALLOC; + + switch (dispatch) + { + case 0: add32_ext (cpu, extensionType, shift); break; + case 1: adds32_ext (cpu, extensionType, shift); break; + case 2: sub32_ext (cpu, extensionType, shift); break; + case 3: subs32_ext (cpu, extensionType, shift); break; + case 4: add64_ext (cpu, extensionType, shift); break; + case 5: adds64_ext (cpu, extensionType, shift); break; + case 6: sub64_ext (cpu, extensionType, shift); break; + case 7: subs64_ext (cpu, extensionType, shift); break; + default: HALT_UNALLOC; + } +} + +/* Conditional data processing + Condition register is implicit 3rd source. */ + +/* 32 bit add with carry. */ +/* N.B register args may not be SP. */ + +static void +adc32 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_reg_u32 (cpu, rn, NO_SP) + + aarch64_get_reg_u32 (cpu, rm, NO_SP) + + IS_SET (C)); +} + +/* 64 bit add with carry */ +static void +adc64 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_reg_u64 (cpu, rn, NO_SP) + + aarch64_get_reg_u64 (cpu, rm, NO_SP) + + IS_SET (C)); +} + +/* 32 bit add with carry setting flags. */ +static void +adcs32 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP); + uint32_t value2 = aarch64_get_reg_u32 (cpu, rm, NO_SP); + uint32_t carry = IS_SET (C); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2 + carry); + set_flags_for_add32 (cpu, value1, value2 + carry); +} + +/* 64 bit add with carry setting flags. */ +static void +adcs64 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP); + uint64_t value2 = aarch64_get_reg_u64 (cpu, rm, NO_SP); + uint64_t carry = IS_SET (C); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 + value2 + carry); + set_flags_for_add64 (cpu, value1, value2 + carry); +} + +/* 32 bit sub with carry. */ +static void +sbc32 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_reg_u32 (cpu, rn, NO_SP) + - aarch64_get_reg_u32 (cpu, rm, NO_SP) + - 1 + IS_SET (C)); +} + +/* 64 bit sub with carry */ +static void +sbc64 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_reg_u64 (cpu, rn, NO_SP) + - aarch64_get_reg_u64 (cpu, rm, NO_SP) + - 1 + IS_SET (C)); +} + +/* 32 bit sub with carry setting flags */ +static void +sbcs32 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP); + uint32_t value2 = aarch64_get_reg_u32 (cpu, rm, NO_SP); + uint32_t carry = IS_SET (C); + uint32_t result = value1 - value2 + 1 - carry; + + aarch64_set_reg_u64 (cpu, rd, NO_SP, result); + set_flags_for_sub32 (cpu, value1, value2 + 1 - carry); +} + +/* 64 bit sub with carry setting flags */ +static void +sbcs64 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP); + uint64_t value2 = aarch64_get_reg_u64 (cpu, rm, NO_SP); + uint64_t carry = IS_SET (C); + uint64_t result = value1 - value2 + 1 - carry; + + aarch64_set_reg_u64 (cpu, rd, NO_SP, result); + set_flags_for_sub64 (cpu, value1, value2 + 1 - carry); +} + +static void +dexAddSubtractWithCarry (sim_cpu *cpu) +{ + /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[30] = op : 0 ==> ADC, 1 ==> SBC + instr[29] = set? : 0 ==> no flags, 1 ==> set flags + instr[28,21] = 1 1010 000 + instr[20,16] = Rm + instr[15,10] = op2 : 00000 ==> ok, ow ==> UNALLOC + instr[9,5] = Rn + instr[4,0] = Rd */ + + uint32_t op2 = uimm (aarch64_get_instr (cpu), 15, 10); + /* Dispatch on size:op:set? i.e aarch64_get_instr (cpu)[31,29] */ + uint32_t dispatch = uimm (aarch64_get_instr (cpu), 31, 29); + + NYI_assert (28, 21, 0xD0); + + if (op2 != 0) + HALT_UNALLOC; + + switch (dispatch) + { + case 0: adc32 (cpu); break; + case 1: adcs32 (cpu); break; + case 2: sbc32 (cpu); break; + case 3: sbcs32 (cpu); break; + case 4: adc64 (cpu); break; + case 5: adcs64 (cpu); break; + case 6: sbc64 (cpu); break; + case 7: sbcs64 (cpu); break; + default: HALT_UNALLOC; + } +} + +static uint32_t +testConditionCode (sim_cpu *cpu, CondCode cc) +{ + /* This should be reduceable to branchless logic + by some careful testing of bits in CC followed + by the requisite masking and combining of bits + from the flag register. + + For now we do it with a switch. */ + int res; + + switch (cc) + { + case EQ: res = IS_SET (Z); break; + case NE: res = IS_CLEAR (Z); break; + case CS: res = IS_SET (C); break; + case CC: res = IS_CLEAR (C); break; + case MI: res = IS_SET (N); break; + case PL: res = IS_CLEAR (N); break; + case VS: res = IS_SET (V); break; + case VC: res = IS_CLEAR (V); break; + case HI: res = IS_SET (C) && IS_CLEAR (Z); break; + case LS: res = IS_CLEAR (C) || IS_SET (Z); break; + case GE: res = IS_SET (N) == IS_SET (V); break; + case LT: res = IS_SET (N) != IS_SET (V); break; + case GT: res = IS_CLEAR (Z) && (IS_SET (N) == IS_SET (V)); break; + case LE: res = IS_SET (Z) || (IS_SET (N) != IS_SET (V)); break; + case AL: + case NV: + default: + res = 1; + break; + } + return res; +} + +static void +CondCompare (sim_cpu *cpu) /* aka: ccmp and ccmn */ +{ + /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[30] = compare with positive (0) or negative value (1) + instr[29,21] = 1 1101 0010 + instr[20,16] = Rm or const + instr[15,12] = cond + instr[11] = compare reg (0) or const (1) + instr[10] = 0 + instr[9,5] = Rn + instr[4] = 0 + instr[3,0] = value for CPSR bits if the comparison does not take place. */ + signed int negate; + unsigned rm; + unsigned rn; + + NYI_assert (29, 21, 0x1d2); + NYI_assert (10, 10, 0); + NYI_assert (4, 4, 0); + + if (! testConditionCode (cpu, uimm (aarch64_get_instr (cpu), 15, 12))) + { + aarch64_set_CPSR (cpu, uimm (aarch64_get_instr (cpu), 3, 0)); + return; + } + + negate = uimm (aarch64_get_instr (cpu), 30, 30) ? -1 : 1; + rm = uimm (aarch64_get_instr (cpu), 20, 16); + rn = uimm (aarch64_get_instr (cpu), 9, 5); + + if (uimm (aarch64_get_instr (cpu), 31, 31)) + { + if (uimm (aarch64_get_instr (cpu), 11, 11)) + set_flags_for_sub64 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK), + negate * (uint64_t) rm); + else + set_flags_for_sub64 (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK), + negate * aarch64_get_reg_u64 (cpu, rm, SP_OK)); + } + else + { + if (uimm (aarch64_get_instr (cpu), 11, 11)) + set_flags_for_sub32 (cpu, aarch64_get_reg_u32 (cpu, rn, SP_OK), + negate * rm); + else + set_flags_for_sub32 (cpu, aarch64_get_reg_u32 (cpu, rn, SP_OK), + negate * aarch64_get_reg_u32 (cpu, rm, SP_OK)); + } +} + +static void +do_vec_MOV_whole_vector (sim_cpu *cpu) +{ + /* MOV Vd.T, Vs.T (alias for ORR Vd.T, Vn.T, Vm.T where Vn == Vm) + + instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,21] = 001110101 + instr[20,16] = Vs + instr[15,10] = 000111 + instr[9,5] = Vs + instr[4,0] = Vd */ + + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (29, 21, 0x075); + NYI_assert (15, 10, 0x07); + + if (uimm (aarch64_get_instr (cpu), 20, 16) != vs) + HALT_NYI; + + if (uimm (aarch64_get_instr (cpu), 30, 30)) + aarch64_set_vec_u64 (cpu, vd, 1, aarch64_get_vec_u64 (cpu, vs, 1)); + + aarch64_set_vec_u64 (cpu, vd, 0, aarch64_get_vec_u64 (cpu, vs, 0)); +} + +static void +do_vec_MOV_into_scalar (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = word(0)/long(1) + instr[29,21] = 00 1110 000 + instr[20,18] = element size and index + instr[17,10] = 00 0011 11 + instr[9,5] = V source + instr[4,0] = R dest */ + + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (29, 21, 0x070); + NYI_assert (17, 10, 0x0F); + + switch (uimm (aarch64_get_instr (cpu), 20, 18)) + { + case 0x2: + aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_vec_u64 (cpu, vs, 0)); + break; + + case 0x6: + aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_vec_u64 (cpu, vs, 1)); + break; + + case 0x1: + case 0x3: + case 0x5: + case 0x7: + aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_vec_u32 + (cpu, vs, uimm (aarch64_get_instr (cpu), 20, 19))); + break; + + default: + HALT_NYI; + } +} + +static void +do_vec_INS (sim_cpu *cpu) +{ + /* instr[31,21] = 01001110000 + instr[20,16] = element size and index + instr[15,10] = 000111 + instr[9,5] = W source + instr[4,0] = V dest */ + + int index; + unsigned rs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (31, 21, 0x270); + NYI_assert (15, 10, 0x07); + + if (uimm (aarch64_get_instr (cpu), 16, 16)) + { + index = uimm (aarch64_get_instr (cpu), 20, 17); + aarch64_set_vec_u8 (cpu, vd, index, + aarch64_get_reg_u8 (cpu, rs, NO_SP)); + } + else if (uimm (aarch64_get_instr (cpu), 17, 17)) + { + index = uimm (aarch64_get_instr (cpu), 20, 18); + aarch64_set_vec_u16 (cpu, vd, index, + aarch64_get_reg_u16 (cpu, rs, NO_SP)); + } + else if (uimm (aarch64_get_instr (cpu), 18, 18)) + { + index = uimm (aarch64_get_instr (cpu), 20, 19); + aarch64_set_vec_u32 (cpu, vd, index, + aarch64_get_reg_u32 (cpu, rs, NO_SP)); + } + else if (uimm (aarch64_get_instr (cpu), 19, 19)) + { + index = uimm (aarch64_get_instr (cpu), 20, 20); + aarch64_set_vec_u64 (cpu, vd, index, + aarch64_get_reg_u64 (cpu, rs, NO_SP)); + } + else + HALT_NYI; +} + +static void +do_vec_DUP_vector_into_vector (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,21] = 00 1110 000 + instr[20,16] = element size and index + instr[15,10] = 0000 01 + instr[9,5] = V source + instr[4,0] = V dest. */ + + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + int i, index; + + NYI_assert (29, 21, 0x070); + NYI_assert (15, 10, 0x01); + + if (uimm (aarch64_get_instr (cpu), 16, 16)) + { + index = uimm (aarch64_get_instr (cpu), 20, 17); + + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u8 (cpu, vs, index)); + } + else if (uimm (aarch64_get_instr (cpu), 17, 17)) + { + index = uimm (aarch64_get_instr (cpu), 20, 18); + + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vs, index)); + } + else if (uimm (aarch64_get_instr (cpu), 18, 18)) + { + index = uimm (aarch64_get_instr (cpu), 20, 19); + + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vs, index)); + } + else + { + if (uimm (aarch64_get_instr (cpu), 19, 19) == 0) + HALT_UNALLOC; + + if (! full) + HALT_UNALLOC; + + index = uimm (aarch64_get_instr (cpu), 20, 20); + + for (i = 0; i < 2; i++) + aarch64_set_vec_u64 (cpu, vd, i, aarch64_get_vec_u64 (cpu, vs, index)); + } +} + +static void +do_vec_TBL (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,21] = 00 1110 000 + instr[20,16] = Vm + instr[15] = 0 + instr[14,13] = vec length + instr[12,10] = 000 + instr[9,5] = V start + instr[4,0] = V dest */ + + int full = uimm (aarch64_get_instr (cpu), 30, 30); + int len = uimm (aarch64_get_instr (cpu), 14, 13) + 1; + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (29, 21, 0x070); + NYI_assert (12, 10, 0); + + for (i = 0; i < (full ? 16 : 8); i++) + { + unsigned int selector = aarch64_get_vec_u8 (cpu, vm, i); + uint8_t val; + + if (selector < 16) + val = aarch64_get_vec_u8 (cpu, vn, selector); + else if (selector < 32) + val = len < 2 ? 0 : aarch64_get_vec_u8 (cpu, vn + 1, selector - 16); + else if (selector < 48) + val = len < 3 ? 0 : aarch64_get_vec_u8 (cpu, vn + 2, selector - 32); + else if (selector < 64) + val = len < 4 ? 0 : aarch64_get_vec_u8 (cpu, vn + 3, selector - 48); + else + val = 0; + + aarch64_set_vec_u8 (cpu, vd, i, val); + } +} + +static void +do_vec_TRN (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,24] = 00 1110 + instr[23,22] = size + instr[21] = 0 + instr[20,16] = Vm + instr[15] = 0 + instr[14] = TRN1 (0) / TRN2 (1) + instr[13,10] = 1010 + instr[9,5] = V source + instr[4,0] = V dest. */ + + int full = uimm (aarch64_get_instr (cpu), 30, 30); + int second = uimm (aarch64_get_instr (cpu), 14, 14); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (29, 24, 0x0E); + NYI_assert (13, 10, 0xA); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 8 : 4); i++) + { + aarch64_set_vec_u8 + (cpu, vd, i * 2, + aarch64_get_vec_u8 (cpu, second ? vm : vn, i * 2)); + aarch64_set_vec_u8 + (cpu, vd, 1 * 2 + 1, + aarch64_get_vec_u8 (cpu, second ? vn : vm, i * 2 + 1)); + } + break; + + case 1: + for (i = 0; i < (full ? 4 : 2); i++) + { + aarch64_set_vec_u16 + (cpu, vd, i * 2, + aarch64_get_vec_u16 (cpu, second ? vm : vn, i * 2)); + aarch64_set_vec_u16 + (cpu, vd, 1 * 2 + 1, + aarch64_get_vec_u16 (cpu, second ? vn : vm, i * 2 + 1)); + } + break; + + case 2: + aarch64_set_vec_u32 + (cpu, vd, 0, aarch64_get_vec_u32 (cpu, second ? vm : vn, 0)); + aarch64_set_vec_u32 + (cpu, vd, 1, aarch64_get_vec_u32 (cpu, second ? vn : vm, 1)); + aarch64_set_vec_u32 + (cpu, vd, 2, aarch64_get_vec_u32 (cpu, second ? vm : vn, 2)); + aarch64_set_vec_u32 + (cpu, vd, 3, aarch64_get_vec_u32 (cpu, second ? vn : vm, 3)); + break; + + case 3: + if (! full) + HALT_UNALLOC; + + aarch64_set_vec_u64 (cpu, vd, 0, + aarch64_get_vec_u64 (cpu, second ? vm : vn, 0)); + aarch64_set_vec_u64 (cpu, vd, 1, + aarch64_get_vec_u64 (cpu, second ? vn : vm, 1)); + break; + + default: + HALT_UNALLOC; + } +} + +static void +do_vec_DUP_scalar_into_vector (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = 0=> zero top 64-bits, 1=> duplicate into top 64-bits + [must be 1 for 64-bit xfer] + instr[29,20] = 00 1110 0000 + instr[19,16] = element size: 0001=> 8-bits, 0010=> 16-bits, + 0100=> 32-bits. 1000=>64-bits + instr[15,10] = 0000 11 + instr[9,5] = W source + instr[4,0] = V dest. */ + + unsigned i; + unsigned Vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned Rs = uimm (aarch64_get_instr (cpu), 9, 5); + int both = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 20, 0x0E0); + NYI_assert (15, 10, 0x03); + + switch (uimm (aarch64_get_instr (cpu), 19, 16)) + { + case 1: + for (i = 0; i < (both ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, Vd, i, aarch64_get_reg_u8 (cpu, Rs, NO_SP)); + break; + + case 2: + for (i = 0; i < (both ? 8 : 4); i++) + aarch64_set_vec_u16 (cpu, Vd, i, aarch64_get_reg_u16 (cpu, Rs, NO_SP)); + break; + + case 4: + for (i = 0; i < (both ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, Vd, i, aarch64_get_reg_u32 (cpu, Rs, NO_SP)); + break; + + case 8: + if (!both) + HALT_NYI; + aarch64_set_vec_u64 (cpu, Vd, 0, aarch64_get_reg_u64 (cpu, Rs, NO_SP)); + aarch64_set_vec_u64 (cpu, Vd, 1, aarch64_get_reg_u64 (cpu, Rs, NO_SP)); + break; + + default: + HALT_NYI; + } +} + +static void +do_vec_UZP (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,24] = 00 1110 + instr[23,22] = size: byte(00), half(01), word (10), long (11) + instr[21] = 0 + instr[20,16] = Vm + instr[15] = 0 + instr[14] = lower (0) / upper (1) + instr[13,10] = 0110 + instr[9,5] = Vn + instr[4,0] = Vd. */ + + int full = uimm (aarch64_get_instr (cpu), 30, 30); + int upper = uimm (aarch64_get_instr (cpu), 14, 14); + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t val_m1 = aarch64_get_vec_u64 (cpu, vm, 0); + uint64_t val_m2 = aarch64_get_vec_u64 (cpu, vm, 1); + uint64_t val_n1 = aarch64_get_vec_u64 (cpu, vn, 0); + uint64_t val_n2 = aarch64_get_vec_u64 (cpu, vn, 1); + + uint64_t val1 = 0; + uint64_t val2 = 0; + + uint64_t input1 = upper ? val_n1 : val_m1; + uint64_t input2 = upper ? val_n2 : val_m2; + unsigned i; + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 21, 0); + NYI_assert (15, 15, 0); + NYI_assert (13, 10, 6); + + switch (uimm (aarch64_get_instr (cpu), 23, 23)) + { + case 0: + for (i = 0; i < 8; i++) + { + val1 |= (input1 >> (i * 8)) & (0xFFULL << (i * 8)); + val2 |= (input2 >> (i * 8)) & (0xFFULL << (i * 8)); + } + break; + + case 1: + for (i = 0; i < 4; i++) + { + val1 |= (input1 >> (i * 16)) & (0xFFFFULL << (i * 16)); + val2 |= (input2 >> (i * 16)) & (0xFFFFULL << (i * 16)); + } + break; + + case 2: + val1 = ((input1 & 0xFFFFFFFF) | ((input1 >> 32) & 0xFFFFFFFF00000000ULL)); + val2 = ((input2 & 0xFFFFFFFF) | ((input2 >> 32) & 0xFFFFFFFF00000000ULL)); + + case 3: + val1 = input1; + val2 = input2; + break; + } + + aarch64_set_vec_u64 (cpu, vd, 0, val1); + if (full) + aarch64_set_vec_u64 (cpu, vd, 1, val2); +} + +static void +do_vec_ZIP (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,24] = 00 1110 + instr[23,22] = size: byte(00), hald(01), word (10), long (11) + instr[21] = 0 + instr[20,16] = Vm + instr[15] = 0 + instr[14] = lower (0) / upper (1) + instr[13,10] = 1110 + instr[9,5] = Vn + instr[4,0] = Vd. */ + + int full = uimm (aarch64_get_instr (cpu), 30, 30); + int upper = uimm (aarch64_get_instr (cpu), 14, 14); + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t val_m1 = aarch64_get_vec_u64 (cpu, vm, 0); + uint64_t val_m2 = aarch64_get_vec_u64 (cpu, vm, 1); + uint64_t val_n1 = aarch64_get_vec_u64 (cpu, vn, 0); + uint64_t val_n2 = aarch64_get_vec_u64 (cpu, vn, 1); + + uint64_t val1 = 0; + uint64_t val2 = 0; + + uint64_t input1 = upper ? val_n1 : val_m1; + uint64_t input2 = upper ? val_n2 : val_m2; + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 21, 0); + NYI_assert (15, 15, 0); + NYI_assert (13, 10, 0xE); + + switch (uimm (aarch64_get_instr (cpu), 23, 23)) + { + case 0: + val1 = + ((input1 << 0) & (0xFF << 0)) + | ((input2 << 8) & (0xFF << 8)) + | ((input1 << 8) & (0xFF << 16)) + | ((input2 << 16) & (0xFF << 24)) + | ((input1 << 16) & (0xFFULL << 32)) + | ((input2 << 24) & (0xFFULL << 40)) + | ((input1 << 24) & (0xFFULL << 48)) + | ((input2 << 32) & (0xFFULL << 56)); + + val2 = + ((input1 >> 32) & (0xFF << 0)) + | ((input2 >> 24) & (0xFF << 8)) + | ((input1 >> 24) & (0xFF << 16)) + | ((input2 >> 16) & (0xFF << 24)) + | ((input1 >> 16) & (0xFFULL << 32)) + | ((input2 >> 8) & (0xFFULL << 40)) + | ((input1 >> 8) & (0xFFULL << 48)) + | ((input2 >> 0) & (0xFFULL << 56)); + break; + + case 1: + val1 = + ((input1 << 0) & (0xFFFF << 0)) + | ((input2 << 16) & (0xFFFF << 16)) + | ((input1 << 16) & (0xFFFFULL << 32)) + | ((input2 << 32) & (0xFFFFULL << 48)); + + val2 = + ((input1 >> 32) & (0xFFFF << 0)) + | ((input2 >> 16) & (0xFFFF << 16)) + | ((input1 >> 16) & (0xFFFFULL << 32)) + | ((input2 >> 0) & (0xFFFFULL << 48)); + break; + + case 2: + val1 = (input1 & 0xFFFFFFFFULL) | (input2 << 32); + val2 = (input2 & 0xFFFFFFFFULL) | (input1 << 32); + break; + + case 3: + val1 = input1; + val2 = input2; + break; + } + + aarch64_set_vec_u64 (cpu, vd, 0, val1); + if (full) + aarch64_set_vec_u64 (cpu, vd, 1, val2); +} + +/* Floating point immediates are encoded in 8 bits. + fpimm[7] = sign bit. + fpimm[6:4] = signed exponent. + fpimm[3:0] = fraction (assuming leading 1). + i.e. F = s * 1.f * 2^(e - b). */ + +static float +fp_immediate_for_encoding_32 (uint32_t imm8) +{ + float u; + uint32_t s, e, f, i; + + s = (imm8 >> 7) & 0x1; + e = (imm8 >> 4) & 0x7; + f = imm8 & 0xf; + + /* The fp value is s * n/16 * 2r where n is 16+e. */ + u = (16.0 + f) / 16.0; + + /* N.B. exponent is signed. */ + if (e < 4) + { + int epos = e; + + for (i = 0; i <= epos; i++) + u *= 2.0; + } + else + { + int eneg = 7 - e; + + for (i = 0; i < eneg; i++) + u /= 2.0; + } + + if (s) + u = - u; + + return u; +} + +static double +fp_immediate_for_encoding_64 (uint32_t imm8) +{ + double u; + uint32_t s, e, f, i; + + s = (imm8 >> 7) & 0x1; + e = (imm8 >> 4) & 0x7; + f = imm8 & 0xf; + + /* The fp value is s * n/16 * 2r where n is 16+e. */ + u = (16.0 + f) / 16.0; + + /* N.B. exponent is signed. */ + if (e < 4) + { + int epos = e; + + for (i = 0; i <= epos; i++) + u *= 2.0; + } + else + { + int eneg = 7 - e; + + for (i = 0; i < eneg; i++) + u /= 2.0; + } + + if (s) + u = - u; + + return u; +} + +static void +do_vec_MOV_immediate (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half selector + instr[29,19] = 00111100000 + instr[18,16] = high 3 bits of uimm8 + instr[15,12] = size & shift: + 0000 => 32-bit + 0010 => 32-bit + LSL#8 + 0100 => 32-bit + LSL#16 + 0110 => 32-bit + LSL#24 + 1010 => 16-bit + LSL#8 + 1000 => 16-bit + 1101 => 32-bit + MSL#16 + 1100 => 32-bit + MSL#8 + 1110 => 8-bit + 1111 => double + instr[11,10] = 01 + instr[9,5] = low 5-bits of uimm8 + instr[4,0] = Vd. */ + + int full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned val = uimm (aarch64_get_instr (cpu), 18, 16) << 5 + | uimm (aarch64_get_instr (cpu), 9, 5); + unsigned i; + + NYI_assert (29, 19, 0x1E0); + NYI_assert (11, 10, 1); + + switch (uimm (aarch64_get_instr (cpu), 15, 12)) + { + case 0x0: /* 32-bit, no shift. */ + case 0x2: /* 32-bit, shift by 8. */ + case 0x4: /* 32-bit, shift by 16. */ + case 0x6: /* 32-bit, shift by 24. */ + val <<= (8 * uimm (aarch64_get_instr (cpu), 14, 13)); + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, val); + break; + + case 0xa: /* 16-bit, shift by 8. */ + val <<= 8; + /* Fall through. */ + case 0x8: /* 16-bit, no shift. */ + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_u16 (cpu, vd, i, val); + /* Fall through. */ + case 0xd: /* 32-bit, mask shift by 16. */ + val <<= 8; + val |= 0xFF; + /* Fall through. */ + case 0xc: /* 32-bit, mask shift by 8. */ + val <<= 8; + val |= 0xFF; + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, val); + break; + + case 0xe: /* 8-bit, no shift. */ + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, val); + break; + + case 0xf: /* FMOV Vs.{2|4}S, #fpimm. */ + { + float u = fp_immediate_for_encoding_32 (val); + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_float (cpu, vd, i, u); + break; + } + + default: + HALT_NYI; + } +} + +static void +do_vec_MVNI (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half selector + instr[29,19] = 10111100000 + instr[18,16] = high 3 bits of uimm8 + instr[15,12] = selector + instr[11,10] = 01 + instr[9,5] = low 5-bits of uimm8 + instr[4,0] = Vd. */ + + int full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned val = uimm (aarch64_get_instr (cpu), 18, 16) << 5 + | uimm (aarch64_get_instr (cpu), 9, 5); + unsigned i; + + NYI_assert (29, 19, 0x5E0); + NYI_assert (11, 10, 1); + + switch (uimm (aarch64_get_instr (cpu), 15, 12)) + { + case 0x0: /* 32-bit, no shift. */ + case 0x2: /* 32-bit, shift by 8. */ + case 0x4: /* 32-bit, shift by 16. */ + case 0x6: /* 32-bit, shift by 24. */ + val <<= (8 * uimm (aarch64_get_instr (cpu), 14, 13)); + val = ~ val; + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, val); + return; + + case 0xa: /* 16-bit, 8 bit shift. */ + val <<= 8; + case 0x8: /* 16-bit, no shift. */ + val = ~ val; + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_u16 (cpu, vd, i, val); + return; + + case 0xd: /* 32-bit, mask shift by 16. */ + val <<= 8; + val |= 0xFF; + case 0xc: /* 32-bit, mask shift by 8. */ + val <<= 8; + val |= 0xFF; + val = ~ val; + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, val); + return; + + case 0xE: /* MOVI Dn, #mask64 */ + { + uint64_t mask = 0; + + for (i = 0; i < 8; i++) + if (val & (1 << i)) + mask |= (0xF << (i * 4)); + aarch64_set_vec_u64 (cpu, vd, 0, mask); + aarch64_set_vec_u64 (cpu, vd, 1, 0); + return; + } + + case 0xf: /* FMOV Vd.2D, #fpimm. */ + { + double u = fp_immediate_for_encoding_64 (val); + + if (! full) + HALT_UNALLOC; + + aarch64_set_vec_double (cpu, vd, 0, u); + aarch64_set_vec_double (cpu, vd, 1, u); + return; + } + + default: + HALT_NYI; + } +} + +#define ABS(A) ((A) < 0 ? - (A) : (A)) + +static void +do_vec_ABS (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,24] = 00 1110 + instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit, 11=> 64-bit + instr[21,10] = 10 0000 1011 10 + instr[9,5] = Vn + instr[4.0] = Vd. */ + + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned i; + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 10, 0x82E); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_s8 (cpu, vd, i, + ABS (aarch64_get_vec_s8 (cpu, vn, i))); + break; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_s16 (cpu, vd, i, + ABS (aarch64_get_vec_s16 (cpu, vn, i))); + break; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_s32 (cpu, vd, i, + ABS (aarch64_get_vec_s32 (cpu, vn, i))); + break; + + case 3: + if (! full) + HALT_NYI; + for (i = 0; i < 2; i++) + aarch64_set_vec_s64 (cpu, vd, i, + ABS (aarch64_get_vec_s64 (cpu, vn, i))); + break; + } +} + +static void +do_vec_ADDV (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half selector + instr[29,24] = 00 1110 + instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit, 11=> 64-bit + instr[21,10] = 11 0001 1011 10 + instr[9,5] = Vm + instr[4.0] = Rd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + uint64_t val = 0; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 10, 0xC6E); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + val += aarch64_get_vec_u8 (cpu, vm, i); + aarch64_set_reg_u64 (cpu, rd, NO_SP, val); + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + val += aarch64_get_vec_u16 (cpu, vm, i); + aarch64_set_reg_u64 (cpu, rd, NO_SP, val); + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + val += aarch64_get_vec_u32 (cpu, vm, i); + aarch64_set_reg_u64 (cpu, rd, NO_SP, val); + return; + + case 3: + if (! full) + HALT_UNALLOC; + val = aarch64_get_vec_u64 (cpu, vm, 0); + val += aarch64_get_vec_u64 (cpu, vm, 1); + aarch64_set_reg_u64 (cpu, rd, NO_SP, val); + return; + + default: + HALT_UNREACHABLE; + } +} + +static void +do_vec_ins_2 (sim_cpu *cpu) +{ + /* instr[31,21] = 01001110000 + instr[20,18] = size & element selector + instr[17,14] = 0000 + instr[13] = direction: to vec(0), from vec (1) + instr[12,10] = 111 + instr[9,5] = Vm + instr[4,0] = Vd. */ + + unsigned elem; + unsigned vm = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (31, 21, 0x270); + NYI_assert (17, 14, 0); + NYI_assert (12, 10, 7); + + if (uimm (aarch64_get_instr (cpu), 13, 13) == 1) + { + if (uimm (aarch64_get_instr (cpu), 18, 18) == 1) + { + /* 32-bit moves. */ + elem = uimm (aarch64_get_instr (cpu), 20, 19); + aarch64_set_reg_u64 (cpu, vd, NO_SP, + aarch64_get_vec_u32 (cpu, vm, elem)); + } + else + { + /* 64-bit moves. */ + if (uimm (aarch64_get_instr (cpu), 19, 19) != 1) + HALT_NYI; + + elem = uimm (aarch64_get_instr (cpu), 20, 20); + aarch64_set_reg_u64 (cpu, vd, NO_SP, + aarch64_get_vec_u64 (cpu, vm, elem)); + } + } + else + { + if (uimm (aarch64_get_instr (cpu), 18, 18) == 1) + { + /* 32-bit moves. */ + elem = uimm (aarch64_get_instr (cpu), 20, 19); + aarch64_set_vec_u32 (cpu, vd, elem, + aarch64_get_reg_u32 (cpu, vm, NO_SP)); + } + else + { + /* 64-bit moves. */ + if (uimm (aarch64_get_instr (cpu), 19, 19) != 1) + HALT_NYI; + + elem = uimm (aarch64_get_instr (cpu), 20, 20); + aarch64_set_vec_u64 (cpu, vd, elem, + aarch64_get_reg_u64 (cpu, vm, NO_SP)); + } + } +} + +static void +do_vec_mull (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = lower(0)/upper(1) selector + instr[29] = signed(0)/unsigned(1) + instr[28,24] = 0 1110 + instr[23,22] = size: 8-bit (00), 16-bit (01), 32-bit (10) + instr[21] = 1 + instr[20,16] = Vm + instr[15,10] = 11 0000 + instr[9,5] = Vn + instr[4.0] = Vd. */ + + int unsign = uimm (aarch64_get_instr (cpu), 29, 29); + int bias = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (28, 24, 0x0E); + NYI_assert (15, 10, 0x30); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + if (bias) + bias = 8; + if (unsign) + for (i = 0; i < 8; i++) + aarch64_set_vec_u16 (cpu, vd, i, + aarch64_get_vec_u8 (cpu, vn, i + bias) + * aarch64_get_vec_u8 (cpu, vm, i + bias)); + else + for (i = 0; i < 8; i++) + aarch64_set_vec_s16 (cpu, vd, i, + aarch64_get_vec_s8 (cpu, vn, i + bias) + * aarch64_get_vec_s8 (cpu, vm, i + bias)); + return; + + case 1: + if (bias) + bias = 4; + if (unsign) + for (i = 0; i < 4; i++) + aarch64_set_vec_u32 (cpu, vd, i, + aarch64_get_vec_u16 (cpu, vn, i + bias) + * aarch64_get_vec_u16 (cpu, vm, i + bias)); + else + for (i = 0; i < 4; i++) + aarch64_set_vec_s32 (cpu, vd, i, + aarch64_get_vec_s16 (cpu, vn, i + bias) + * aarch64_get_vec_s16 (cpu, vm, i + bias)); + return; + + case 2: + if (bias) + bias = 2; + if (unsign) + for (i = 0; i < 2; i++) + aarch64_set_vec_u64 (cpu, vd, i, + (uint64_t) aarch64_get_vec_u32 (cpu, vn, + i + bias) + * (uint64_t) aarch64_get_vec_u32 (cpu, vm, + i + bias)); + else + for (i = 0; i < 2; i++) + aarch64_set_vec_s64 (cpu, vd, i, + aarch64_get_vec_s32 (cpu, vn, i + bias) + * aarch64_get_vec_s32 (cpu, vm, i + bias)); + return; + + case 3: + default: + HALT_NYI; + } +} + +static void +do_vec_fadd (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,24] = 001110 + instr[23] = FADD(0)/FSUB(1) + instr[22] = float (0)/double(1) + instr[21] = 1 + instr[20,16] = Vm + instr[15,10] = 110101 + instr[9,5] = Vn + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x35); + + if (uimm (aarch64_get_instr (cpu), 23, 23)) + { + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + if (! full) + HALT_NYI; + + for (i = 0; i < 2; i++) + aarch64_set_vec_double (cpu, vd, i, + aarch64_get_vec_double (cpu, vn, i) + - aarch64_get_vec_double (cpu, vm, i)); + } + else + { + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_float (cpu, vd, i, + aarch64_get_vec_float (cpu, vn, i) + - aarch64_get_vec_float (cpu, vm, i)); + } + } + else + { + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + if (! full) + HALT_NYI; + + for (i = 0; i < 2; i++) + aarch64_set_vec_double (cpu, vd, i, + aarch64_get_vec_double (cpu, vm, i) + + aarch64_get_vec_double (cpu, vn, i)); + } + else + { + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_float (cpu, vd, i, + aarch64_get_vec_float (cpu, vm, i) + + aarch64_get_vec_float (cpu, vn, i)); + } + } +} + +static void +do_vec_add (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half selector + instr[29,24] = 001110 + instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit, 11=> 64-bit + instr[21] = 1 + instr[20,16] = Vn + instr[15,10] = 100001 + instr[9,5] = Vm + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x21); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u8 (cpu, vn, i) + + aarch64_get_vec_u8 (cpu, vm, i)); + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vn, i) + + aarch64_get_vec_u16 (cpu, vm, i)); + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vn, i) + + aarch64_get_vec_u32 (cpu, vm, i)); + return; + + case 3: + if (! full) + HALT_UNALLOC; + aarch64_set_vec_u64 (cpu, vd, 0, aarch64_get_vec_u64 (cpu, vn, 0) + + aarch64_get_vec_u64 (cpu, vm, 0)); + aarch64_set_vec_u64 (cpu, vd, 1, + aarch64_get_vec_u64 (cpu, vn, 1) + + aarch64_get_vec_u64 (cpu, vm, 1)); + return; + + default: + HALT_UNREACHABLE; + } +} + +static void +do_vec_mul (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half selector + instr[29,24] = 00 1110 + instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit + instr[21] = 1 + instr[20,16] = Vn + instr[15,10] = 10 0111 + instr[9,5] = Vm + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x27); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + { + uint16_t val = aarch64_get_vec_u8 (cpu, vn, i); + val *= aarch64_get_vec_u8 (cpu, vm, i); + + aarch64_set_vec_u16 (cpu, vd, i, val); + } + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + { + uint32_t val = aarch64_get_vec_u16 (cpu, vn, i); + val *= aarch64_get_vec_u16 (cpu, vm, i); + + aarch64_set_vec_u32 (cpu, vd, i, val); + } + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + { + uint64_t val = aarch64_get_vec_u32 (cpu, vn, i); + val *= aarch64_get_vec_u32 (cpu, vm, i); + + aarch64_set_vec_u64 (cpu, vd, i, val); + } + return; + + default: + case 3: + HALT_UNALLOC; + } +} + +static void +do_vec_MLA (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half selector + instr[29,24] = 00 1110 + instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit + instr[21] = 1 + instr[20,16] = Vn + instr[15,10] = 1001 01 + instr[9,5] = Vm + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x25); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + { + uint16_t val = aarch64_get_vec_u8 (cpu, vn, i); + val *= aarch64_get_vec_u8 (cpu, vm, i); + val += aarch64_get_vec_u8 (cpu, vd, i); + + aarch64_set_vec_u16 (cpu, vd, i, val); + } + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + { + uint32_t val = aarch64_get_vec_u16 (cpu, vn, i); + val *= aarch64_get_vec_u16 (cpu, vm, i); + val += aarch64_get_vec_u16 (cpu, vd, i); + + aarch64_set_vec_u32 (cpu, vd, i, val); + } + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + { + uint64_t val = aarch64_get_vec_u32 (cpu, vn, i); + val *= aarch64_get_vec_u32 (cpu, vm, i); + val += aarch64_get_vec_u32 (cpu, vd, i); + + aarch64_set_vec_u64 (cpu, vd, i, val); + } + return; + + default: + case 3: + HALT_UNALLOC; + } +} + +static float +fmaxnm (float a, float b) +{ + if (fpclassify (a) == FP_NORMAL) + { + if (fpclassify (b) == FP_NORMAL) + return a > b ? a : b; + return a; + } + else if (fpclassify (b) == FP_NORMAL) + return b; + return a; +} + +static float +fminnm (float a, float b) +{ + if (fpclassify (a) == FP_NORMAL) + { + if (fpclassify (b) == FP_NORMAL) + return a < b ? a : b; + return a; + } + else if (fpclassify (b) == FP_NORMAL) + return b; + return a; +} + +static double +dmaxnm (double a, double b) +{ + if (fpclassify (a) == FP_NORMAL) + { + if (fpclassify (b) == FP_NORMAL) + return a > b ? a : b; + return a; + } + else if (fpclassify (b) == FP_NORMAL) + return b; + return a; +} + +static double +dminnm (double a, double b) +{ + if (fpclassify (a) == FP_NORMAL) + { + if (fpclassify (b) == FP_NORMAL) + return a < b ? a : b; + return a; + } + else if (fpclassify (b) == FP_NORMAL) + return b; + return a; +} + +static void +do_vec_FminmaxNMP (sim_cpu *cpu) +{ + /* aarch64_get_instr (cpu)[31] = 0 + aarch64_get_instr (cpu)[30] = half (0)/full (1) + aarch64_get_instr (cpu)[29,24] = 10 1110 + aarch64_get_instr (cpu)[23] = max(0)/min(1) + aarch64_get_instr (cpu)[22] = float (0)/double (1) + aarch64_get_instr (cpu)[21] = 1 + aarch64_get_instr (cpu)[20,16] = Vn + aarch64_get_instr (cpu)[15,10] = 1100 01 + aarch64_get_instr (cpu)[9,5] = Vm + aarch64_get_instr (cpu)[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 24, 0x2E); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x31); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + double (* fn)(double, double) = uimm (aarch64_get_instr (cpu), 23, 23) + ? dminnm : dmaxnm; + + if (! full) + HALT_NYI; + aarch64_set_vec_double (cpu, vd, 0, + fn (aarch64_get_vec_double (cpu, vn, 0), + aarch64_get_vec_double (cpu, vn, 1))); + aarch64_set_vec_double (cpu, vd, 0, + fn (aarch64_get_vec_double (cpu, vm, 0), + aarch64_get_vec_double (cpu, vm, 1))); + } + else + { + float (* fn)(float, float) = uimm (aarch64_get_instr (cpu), 23, 23) + ? fminnm : fmaxnm; + + aarch64_set_vec_float (cpu, vd, 0, + fn (aarch64_get_vec_float (cpu, vn, 0), + aarch64_get_vec_float (cpu, vn, 1))); + if (full) + aarch64_set_vec_float (cpu, vd, 1, + fn (aarch64_get_vec_float (cpu, vn, 2), + aarch64_get_vec_float (cpu, vn, 3))); + + aarch64_set_vec_float (cpu, vd, (full ? 2 : 1), + fn (aarch64_get_vec_float (cpu, vm, 0), + aarch64_get_vec_float (cpu, vm, 1))); + if (full) + aarch64_set_vec_float (cpu, vd, 3, + fn (aarch64_get_vec_float (cpu, vm, 2), + aarch64_get_vec_float (cpu, vm, 3))); + } +} + +static void +do_vec_AND (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half (0)/full (1) + instr[29,21] = 001110001 + instr[20,16] = Vm + instr[15,10] = 000111 + instr[9,5] = Vn + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 21, 0x071); + NYI_assert (15, 10, 0x07); + + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, + aarch64_get_vec_u32 (cpu, vn, i) + & aarch64_get_vec_u32 (cpu, vm, i)); +} + +static void +do_vec_BSL (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half (0)/full (1) + instr[29,21] = 101110011 + instr[20,16] = Vm + instr[15,10] = 000111 + instr[9,5] = Vn + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 21, 0x173); + NYI_assert (15, 10, 0x07); + + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, + ( aarch64_get_vec_u8 (cpu, vd, i) + & aarch64_get_vec_u8 (cpu, vn, i)) + | ((~ aarch64_get_vec_u8 (cpu, vd, i)) + & aarch64_get_vec_u8 (cpu, vm, i))); +} + +static void +do_vec_EOR (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half (0)/full (1) + instr[29,21] = 10 1110 001 + instr[20,16] = Vm + instr[15,10] = 000111 + instr[9,5] = Vn + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 21, 0x171); + NYI_assert (15, 10, 0x07); + + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, + aarch64_get_vec_u32 (cpu, vn, i) + ^ aarch64_get_vec_u32 (cpu, vm, i)); +} + +static void +do_vec_bit (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half (0)/full (1) + instr[29,23] = 10 1110 1 + instr[22] = BIT (0) / BIF (1) + instr[21] = 1 + instr[20,16] = Vm + instr[15,10] = 0001 11 + instr[9,5] = Vn + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned test_false = uimm (aarch64_get_instr (cpu), 22, 22); + unsigned i; + + NYI_assert (29, 23, 0x5D); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x07); + + if (test_false) + { + for (i = 0; i < (full ? 16 : 8); i++) + if (aarch64_get_vec_u32 (cpu, vn, i) == 0) + aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vm, i)); + } + else + { + for (i = 0; i < (full ? 16 : 8); i++) + if (aarch64_get_vec_u32 (cpu, vn, i) != 0) + aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vm, i)); + } +} + +static void +do_vec_ORN (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half (0)/full (1) + instr[29,21] = 00 1110 111 + instr[20,16] = Vm + instr[15,10] = 00 0111 + instr[9,5] = Vn + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 21, 0x077); + NYI_assert (15, 10, 0x07); + + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, + aarch64_get_vec_u8 (cpu, vn, i) + | ~ aarch64_get_vec_u8 (cpu, vm, i)); +} + +static void +do_vec_ORR (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half (0)/full (1) + instr[29,21] = 00 1110 101 + instr[20,16] = Vm + instr[15,10] = 0001 11 + instr[9,5] = Vn + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 21, 0x075); + NYI_assert (15, 10, 0x07); + + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, + aarch64_get_vec_u8 (cpu, vn, i) + | aarch64_get_vec_u8 (cpu, vm, i)); +} + +static void +do_vec_BIC (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half (0)/full (1) + instr[29,21] = 00 1110 011 + instr[20,16] = Vm + instr[15,10] = 00 0111 + instr[9,5] = Vn + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 21, 0x073); + NYI_assert (15, 10, 0x07); + + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, + aarch64_get_vec_u8 (cpu, vn, i) + & ~ aarch64_get_vec_u8 (cpu, vm, i)); +} + +static void +do_vec_XTN (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = first part (0)/ second part (1) + instr[29,24] = 00 1110 + instr[23,22] = size: byte(00), half(01), word (10) + instr[21,10] = 1000 0100 1010 + instr[9,5] = Vs + instr[4,0] = Vd. */ + + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned bias = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned i; + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 10, 0x84A); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + if (bias) + for (i = 0; i < 8; i++) + aarch64_set_vec_u8 (cpu, vd, i + 8, + aarch64_get_vec_u16 (cpu, vs, i) >> 8); + else + for (i = 0; i < 8; i++) + aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vs, i)); + return; + + case 1: + if (bias) + for (i = 0; i < 4; i++) + aarch64_set_vec_u16 (cpu, vd, i + 4, + aarch64_get_vec_u32 (cpu, vs, i) >> 16); + else + for (i = 0; i < 4; i++) + aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vs, i)); + return; + + case 2: + if (bias) + for (i = 0; i < 2; i++) + aarch64_set_vec_u32 (cpu, vd, i + 4, + aarch64_get_vec_u64 (cpu, vs, i) >> 32); + else + for (i = 0; i < 2; i++) + aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u64 (cpu, vs, i)); + return; + + default: + HALT_UNALLOC; + } +} + +#define MAX(A,B) ((A) > (B) ? (A) : (B)) +#define MIN(A,B) ((A) < (B) ? (A) : (B)) + +static void +do_vec_maxv (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29] = signed (0)/unsigned(1) + instr[28,24] = 0 1110 + instr[23,22] = size: byte(00), half(01), word (10) + instr[21] = 1 + instr[20,17] = 1 000 + instr[16] = max(0)/min(1) + instr[15,10] = 1010 10 + instr[9,5] = V source + instr[4.0] = R dest. */ + + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned i; + + NYI_assert (28, 24, 0x0E); + NYI_assert (21, 21, 1); + NYI_assert (20, 17, 8); + NYI_assert (15, 10, 0x2A); + + switch ((uimm (aarch64_get_instr (cpu), 29, 29) << 1) + | uimm (aarch64_get_instr (cpu), 16, 16)) + { + case 0: /* SMAXV. */ + { + int64_t smax; + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + smax = aarch64_get_vec_s8 (cpu, vs, 0); + for (i = 1; i < (full ? 16 : 8); i++) + smax = MAX (smax, aarch64_get_vec_s8 (cpu, vs, i)); + break; + case 1: + smax = aarch64_get_vec_s16 (cpu, vs, 0); + for (i = 1; i < (full ? 8 : 4); i++) + smax = MAX (smax, aarch64_get_vec_s16 (cpu, vs, i)); + break; + case 2: + smax = aarch64_get_vec_s32 (cpu, vs, 0); + for (i = 1; i < (full ? 4 : 2); i++) + smax = MAX (smax, aarch64_get_vec_s32 (cpu, vs, i)); + break; + default: + case 3: + HALT_UNALLOC; + } + aarch64_set_reg_s64 (cpu, rd, NO_SP, smax); + return; + } + + case 1: /* SMINV. */ + { + int64_t smin; + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + smin = aarch64_get_vec_s8 (cpu, vs, 0); + for (i = 1; i < (full ? 16 : 8); i++) + smin = MIN (smin, aarch64_get_vec_s8 (cpu, vs, i)); + break; + case 1: + smin = aarch64_get_vec_s16 (cpu, vs, 0); + for (i = 1; i < (full ? 8 : 4); i++) + smin = MIN (smin, aarch64_get_vec_s16 (cpu, vs, i)); + break; + case 2: + smin = aarch64_get_vec_s32 (cpu, vs, 0); + for (i = 1; i < (full ? 4 : 2); i++) + smin = MIN (smin, aarch64_get_vec_s32 (cpu, vs, i)); + break; + default: + case 3: + HALT_UNALLOC; + } + aarch64_set_reg_s64 (cpu, rd, NO_SP, smin); + return; + } + + case 2: /* UMAXV. */ + { + uint64_t umax; + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + umax = aarch64_get_vec_u8 (cpu, vs, 0); + for (i = 1; i < (full ? 16 : 8); i++) + umax = MAX (umax, aarch64_get_vec_u8 (cpu, vs, i)); + break; + case 1: + umax = aarch64_get_vec_u16 (cpu, vs, 0); + for (i = 1; i < (full ? 8 : 4); i++) + umax = MAX (umax, aarch64_get_vec_u16 (cpu, vs, i)); + break; + case 2: + umax = aarch64_get_vec_u32 (cpu, vs, 0); + for (i = 1; i < (full ? 4 : 2); i++) + umax = MAX (umax, aarch64_get_vec_u32 (cpu, vs, i)); + break; + default: + case 3: + HALT_UNALLOC; + } + aarch64_set_reg_u64 (cpu, rd, NO_SP, umax); + return; + } + + case 3: /* UMINV. */ + { + uint64_t umin; + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + umin = aarch64_get_vec_u8 (cpu, vs, 0); + for (i = 1; i < (full ? 16 : 8); i++) + umin = MIN (umin, aarch64_get_vec_u8 (cpu, vs, i)); + break; + case 1: + umin = aarch64_get_vec_u16 (cpu, vs, 0); + for (i = 1; i < (full ? 8 : 4); i++) + umin = MIN (umin, aarch64_get_vec_u16 (cpu, vs, i)); + break; + case 2: + umin = aarch64_get_vec_u32 (cpu, vs, 0); + for (i = 1; i < (full ? 4 : 2); i++) + umin = MIN (umin, aarch64_get_vec_u32 (cpu, vs, i)); + break; + default: + case 3: + HALT_UNALLOC; + } + aarch64_set_reg_u64 (cpu, rd, NO_SP, umin); + return; + } + + default: + HALT_UNALLOC; + } +} + +static void +do_vec_fminmaxV (sim_cpu *cpu) +{ + /* instr[31,24] = 0110 1110 + instr[23] = max(0)/min(1) + instr[22,14] = 011 0000 11 + instr[13,12] = nm(00)/normal(11) + instr[11,10] = 10 + instr[9,5] = V source + instr[4.0] = R dest. */ + + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + float res = aarch64_get_vec_float (cpu, vs, 0); + + NYI_assert (31, 24, 0x6E); + NYI_assert (22, 14, 0x0C3); + NYI_assert (11, 10, 2); + + if (uimm (aarch64_get_instr (cpu), 23, 23)) + { + switch (uimm (aarch64_get_instr (cpu), 13, 12)) + { + case 0: /* FMNINNMV. */ + for (i = 1; i < 4; i++) + res = fminnm (res, aarch64_get_vec_float (cpu, vs, i)); + break; + + case 3: /* FMINV. */ + for (i = 1; i < 4; i++) + res = MIN (res, aarch64_get_vec_float (cpu, vs, i)); + break; + + default: + HALT_NYI; + } + } + else + { + switch (uimm (aarch64_get_instr (cpu), 13, 12)) + { + case 0: /* FMNAXNMV. */ + for (i = 1; i < 4; i++) + res = fmaxnm (res, aarch64_get_vec_float (cpu, vs, i)); + break; + + case 3: /* FMAXV. */ + for (i = 1; i < 4; i++) + res = MAX (res, aarch64_get_vec_float (cpu, vs, i)); + break; + + default: + HALT_NYI; + } + } + + aarch64_set_FP_float (cpu, rd, res); +} + +static void +do_vec_Fminmax (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,24] = 00 1110 + instr[23] = max(0)/min(1) + instr[22] = float(0)/double(1) + instr[21] = 1 + instr[20,16] = Vm + instr[15,14] = 11 + instr[13,12] = nm(00)/normal(11) + instr[11,10] = 01 + instr[9,5] = Vn + instr[4,0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned min = uimm (aarch64_get_instr (cpu), 23, 23); + unsigned i; + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 21, 1); + NYI_assert (15, 14, 3); + NYI_assert (11, 10, 1); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + double (* func)(double, double); + + if (! full) + HALT_NYI; + + if (uimm (aarch64_get_instr (cpu), 13, 12) == 0) + func = min ? dminnm : dmaxnm; + else if (uimm (aarch64_get_instr (cpu), 13, 12) == 3) + func = min ? fmin : fmax; + else + HALT_NYI; + + for (i = 0; i < 2; i++) + aarch64_set_vec_double (cpu, vd, i, + func (aarch64_get_vec_double (cpu, vn, i), + aarch64_get_vec_double (cpu, vm, i))); + } + else + { + float (* func)(float, float); + + if (uimm (aarch64_get_instr (cpu), 13, 12) == 0) + func = min ? fminnm : fmaxnm; + else if (uimm (aarch64_get_instr (cpu), 13, 12) == 3) + func = min ? fminf : fmaxf; + else + HALT_NYI; + + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_float (cpu, vd, i, + func (aarch64_get_vec_float (cpu, vn, i), + aarch64_get_vec_float (cpu, vm, i))); + } +} + +static void +do_vec_SCVTF (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = Q + instr[29,23] = 00 1110 0 + instr[22] = float(0)/double(1) + instr[21,10] = 10 0001 1101 10 + instr[9,5] = Vn + instr[4,0] = Vd. */ + + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned size = uimm (aarch64_get_instr (cpu), 22, 22); + unsigned i; + + NYI_assert (29, 23, 0x1C); + NYI_assert (21, 10, 0x876); + + if (size) + { + if (! full) + HALT_UNALLOC; + + for (i = 0; i < 2; i++) + { + double val = (double) aarch64_get_vec_u64 (cpu, vn, i); + aarch64_set_vec_double (cpu, vd, i, val); + } + } + else + { + for (i = 0; i < (full ? 4 : 2); i++) + { + float val = (float) aarch64_get_vec_u32 (cpu, vn, i); + aarch64_set_vec_float (cpu, vd, i, val); + } + } +} + +#define VEC_CMP(SOURCE, CMP) \ + do \ + { \ + switch (size) \ + { \ + case 0: \ + for (i = 0; i < (full ? 16 : 8); i++) \ + aarch64_set_vec_u8 (cpu, vd, i, \ + aarch64_get_vec_##SOURCE##8 (cpu, vn, i) \ + CMP \ + aarch64_get_vec_##SOURCE##8 (cpu, vm, i) \ + ? -1 : 0); \ + return; \ + case 1: \ + for (i = 0; i < (full ? 8 : 4); i++) \ + aarch64_set_vec_u16 (cpu, vd, i, \ + aarch64_get_vec_##SOURCE##16 (cpu, vn, i) \ + CMP \ + aarch64_get_vec_##SOURCE##16 (cpu, vm, i) \ + ? -1 : 0); \ + return; \ + case 2: \ + for (i = 0; i < (full ? 4 : 2); i++) \ + aarch64_set_vec_u32 (cpu, vd, i, \ + aarch64_get_vec_##SOURCE##32 (cpu, vn, i) \ + CMP \ + aarch64_get_vec_##SOURCE##32 (cpu, vm, i) \ + ? -1 : 0); \ + return; \ + case 3: \ + if (! full) \ + HALT_UNALLOC; \ + for (i = 0; i < 2; i++) \ + aarch64_set_vec_u64 (cpu, vd, i, \ + aarch64_get_vec_##SOURCE##64 (cpu, vn, i) \ + CMP \ + aarch64_get_vec_##SOURCE##64 (cpu, vm, i) \ + ? -1ULL : 0); \ + return; \ + default: \ + HALT_UNALLOC; \ + } \ + } \ + while (0) + +#define VEC_CMP0(SOURCE, CMP) \ + do \ + { \ + switch (size) \ + { \ + case 0: \ + for (i = 0; i < (full ? 16 : 8); i++) \ + aarch64_set_vec_u8 (cpu, vd, i, \ + aarch64_get_vec_##SOURCE##8 (cpu, vn, i) \ + CMP 0 ? -1 : 0); \ + return; \ + case 1: \ + for (i = 0; i < (full ? 8 : 4); i++) \ + aarch64_set_vec_u16 (cpu, vd, i, \ + aarch64_get_vec_##SOURCE##16 (cpu, vn, i) \ + CMP 0 ? -1 : 0); \ + return; \ + case 2: \ + for (i = 0; i < (full ? 4 : 2); i++) \ + aarch64_set_vec_u32 (cpu, vd, i, \ + aarch64_get_vec_##SOURCE##32 (cpu, vn, i) \ + CMP 0 ? -1 : 0); \ + return; \ + case 3: \ + if (! full) \ + HALT_UNALLOC; \ + for (i = 0; i < 2; i++) \ + aarch64_set_vec_u64 (cpu, vd, i, \ + aarch64_get_vec_##SOURCE##64 (cpu, vn, i) \ + CMP 0 ? -1ULL : 0); \ + return; \ + default: \ + HALT_UNALLOC; \ + } \ + } \ + while (0) + +#define VEC_FCMP0(CMP) \ + do \ + { \ + if (vm != 0) \ + HALT_NYI; \ + if (uimm (aarch64_get_instr (cpu), 22, 22)) \ + { \ + if (! full) \ + HALT_NYI; \ + for (i = 0; i < 2; i++) \ + aarch64_set_vec_u64 (cpu, vd, i, \ + aarch64_get_vec_double (cpu, vn, i) \ + CMP 0.0 ? -1 : 0); \ + } \ + else \ + { \ + for (i = 0; i < (full ? 4 : 2); i++) \ + aarch64_set_vec_u32 (cpu, vd, i, \ + aarch64_get_vec_float (cpu, vn, i) \ + CMP 0.0 ? -1 : 0); \ + } \ + return; \ + } \ + while (0) + +#define VEC_FCMP(CMP) \ + do \ + { \ + if (uimm (aarch64_get_instr (cpu), 22, 22)) \ + { \ + if (! full) \ + HALT_NYI; \ + for (i = 0; i < 2; i++) \ + aarch64_set_vec_u64 (cpu, vd, i, \ + aarch64_get_vec_double (cpu, vn, i) \ + CMP \ + aarch64_get_vec_double (cpu, vm, i) \ + ? -1 : 0); \ + } \ + else \ + { \ + for (i = 0; i < (full ? 4 : 2); i++) \ + aarch64_set_vec_u32 (cpu, vd, i, \ + aarch64_get_vec_float (cpu, vn, i) \ + CMP \ + aarch64_get_vec_float (cpu, vm, i) \ + ? -1 : 0); \ + } \ + return; \ + } \ + while (0) + +static void +do_vec_compare (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29] = part-of-comparison-type + instr[28,24] = 0 1110 + instr[23,22] = size of integer compares: byte(00), half(01), word (10), long (11) + type of float compares: single (-0) / double (-1) + instr[21] = 1 + instr[20,16] = Vm or 00000 (compare vs 0) + instr[15,10] = part-of-comparison-type + instr[9,5] = Vn + instr[4.0] = Vd. */ + + int full = uimm (aarch64_get_instr (cpu), 30, 30); + int size = uimm (aarch64_get_instr (cpu), 23, 22); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (28, 24, 0x0E); + NYI_assert (21, 21, 1); + + if ((uimm (aarch64_get_instr (cpu), 11, 11) + && uimm (aarch64_get_instr (cpu), 14, 14)) + || ((uimm (aarch64_get_instr (cpu), 11, 11) == 0 + && uimm (aarch64_get_instr (cpu), 10, 10) == 0))) + { + /* A compare vs 0. */ + if (vm != 0) + { + if (uimm (aarch64_get_instr (cpu), 15, 10) == 0x2A) + do_vec_maxv (cpu); + else if (uimm (aarch64_get_instr (cpu), 15, 10) == 0x32 + || uimm (aarch64_get_instr (cpu), 15, 10) == 0x3E) + do_vec_fminmaxV (cpu); + else if (uimm (aarch64_get_instr (cpu), 29, 23) == 0x1C + && uimm (aarch64_get_instr (cpu), 21, 10) == 0x876) + do_vec_SCVTF (cpu); + else + HALT_NYI; + return; + } + } + + if (uimm (aarch64_get_instr (cpu), 14, 14)) + { + /* A floating point compare. */ + unsigned decode = (uimm (aarch64_get_instr (cpu), 29, 29) << 5) + | (uimm (aarch64_get_instr (cpu), 23, 23) << 4) + | uimm (aarch64_get_instr (cpu), 13, 10); + + NYI_assert (15, 15, 1); + + switch (decode) + { + case /* 0b010010: GT#0 */ 0x12: VEC_FCMP0 (>); + case /* 0b110010: GE#0 */ 0x32: VEC_FCMP0 (>=); + case /* 0b010110: EQ#0 */ 0x16: VEC_FCMP0 (==); + case /* 0b110110: LE#0 */ 0x36: VEC_FCMP0 (<=); + case /* 0b011010: LT#0 */ 0x1A: VEC_FCMP0 (<); + case /* 0b111001: GT */ 0x39: VEC_FCMP (>); + case /* 0b101001: GE */ 0x29: VEC_FCMP (>=); + case /* 0b001001: EQ */ 0x09: VEC_FCMP (==); + + default: + HALT_NYI; + } + } + else + { + unsigned decode = (uimm (aarch64_get_instr (cpu), 29, 29) << 6) + | uimm (aarch64_get_instr (cpu), 15, 10); + + switch (decode) + { + case 0x0D: /* 0001101 GT */ VEC_CMP (s, > ); + case 0x0F: /* 0001111 GE */ VEC_CMP (s, >= ); + case 0x22: /* 0100010 GT #0 */ VEC_CMP0 (s, > ); + case 0x26: /* 0100110 EQ #0 */ VEC_CMP0 (s, == ); + case 0x2A: /* 0101010 LT #0 */ VEC_CMP0 (s, < ); + case 0x4D: /* 1001101 HI */ VEC_CMP (u, > ); + case 0x4F: /* 1001111 HS */ VEC_CMP (u, >= ); + case 0x62: /* 1100010 GE #0 */ VEC_CMP0 (s, >= ); + case 0x63: /* 1100011 EQ */ VEC_CMP (u, == ); + case 0x66: /* 1100110 LE #0 */ VEC_CMP0 (s, <= ); + default: + if (vm == 0) + HALT_NYI; + do_vec_maxv (cpu); + } + } +} + +static void +do_vec_SSHL (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = first part (0)/ second part (1) + instr[29,24] = 00 1110 + instr[23,22] = size: byte(00), half(01), word (10), long (11) + instr[21] = 1 + instr[20,16] = Vm + instr[15,10] = 0100 01 + instr[9,5] = Vn + instr[4,0] = Vd. */ + + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x11); + + /* FIXME: What is a signed shift left in this context ?. */ + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_s8 (cpu, vd, i, aarch64_get_vec_s8 (cpu, vn, i) + << aarch64_get_vec_s8 (cpu, vm, i)); + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_s16 (cpu, vd, i, aarch64_get_vec_s16 (cpu, vn, i) + << aarch64_get_vec_s16 (cpu, vm, i)); + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_s32 (cpu, vd, i, aarch64_get_vec_s32 (cpu, vn, i) + << aarch64_get_vec_s32 (cpu, vm, i)); + return; + + case 3: + if (! full) + HALT_UNALLOC; + for (i = 0; i < 2; i++) + aarch64_set_vec_s64 (cpu, vd, i, aarch64_get_vec_s64 (cpu, vn, i) + << aarch64_get_vec_s64 (cpu, vm, i)); + return; + + default: + HALT_NYI; + } +} + +static void +do_vec_USHL (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = first part (0)/ second part (1) + instr[29,24] = 10 1110 + instr[23,22] = size: byte(00), half(01), word (10), long (11) + instr[21] = 1 + instr[20,16] = Vm + instr[15,10] = 0100 01 + instr[9,5] = Vn + instr[4,0] = Vd */ + + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (29, 24, 0x2E); + NYI_assert (15, 10, 0x11); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, aarch64_get_vec_u8 (cpu, vn, i) + << aarch64_get_vec_u8 (cpu, vm, i)); + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_u16 (cpu, vd, i, aarch64_get_vec_u16 (cpu, vn, i) + << aarch64_get_vec_u16 (cpu, vm, i)); + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, aarch64_get_vec_u32 (cpu, vn, i) + << aarch64_get_vec_u32 (cpu, vm, i)); + return; + + case 3: + if (! full) + HALT_UNALLOC; + for (i = 0; i < 2; i++) + aarch64_set_vec_u64 (cpu, vd, i, aarch64_get_vec_u64 (cpu, vn, i) + << aarch64_get_vec_u64 (cpu, vm, i)); + return; + + default: + HALT_NYI; + } +} + +static void +do_vec_FMLA (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half selector + instr[29,23] = 0011100 + instr[22] = size: 0=>float, 1=>double + instr[21] = 1 + instr[20,16] = Vn + instr[15,10] = 1100 11 + instr[9,5] = Vm + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 23, 0x1C); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x33); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + if (! full) + HALT_UNALLOC; + for (i = 0; i < 2; i++) + aarch64_set_vec_double (cpu, vd, i, + aarch64_get_vec_double (cpu, vn, i) * + aarch64_get_vec_double (cpu, vm, i) + + aarch64_get_vec_double (cpu, vd, i)); + } + else + { + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_float (cpu, vd, i, + aarch64_get_vec_float (cpu, vn, i) * + aarch64_get_vec_float (cpu, vm, i) + + aarch64_get_vec_float (cpu, vd, i)); + } +} + +static void +do_vec_max (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half selector + instr[29] = SMAX (0) / UMAX (1) + instr[28,24] = 0 1110 + instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit + instr[21] = 1 + instr[20,16] = Vn + instr[15,10] = 0110 01 + instr[9,5] = Vm + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (28, 24, 0x0E); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x19); + + if (uimm (aarch64_get_instr (cpu), 29, 29)) + { + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, + aarch64_get_vec_u8 (cpu, vn, i) + > aarch64_get_vec_u8 (cpu, vm, i) + ? aarch64_get_vec_u8 (cpu, vn, i) + : aarch64_get_vec_u8 (cpu, vm, i)); + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_u16 (cpu, vd, i, + aarch64_get_vec_u16 (cpu, vn, i) + > aarch64_get_vec_u16 (cpu, vm, i) + ? aarch64_get_vec_u16 (cpu, vn, i) + : aarch64_get_vec_u16 (cpu, vm, i)); + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, + aarch64_get_vec_u32 (cpu, vn, i) + > aarch64_get_vec_u32 (cpu, vm, i) + ? aarch64_get_vec_u32 (cpu, vn, i) + : aarch64_get_vec_u32 (cpu, vm, i)); + return; + + default: + case 3: + HALT_UNALLOC; + } + } + else + { + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_s8 (cpu, vd, i, + aarch64_get_vec_s8 (cpu, vn, i) + > aarch64_get_vec_s8 (cpu, vm, i) + ? aarch64_get_vec_s8 (cpu, vn, i) + : aarch64_get_vec_s8 (cpu, vm, i)); + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_s16 (cpu, vd, i, + aarch64_get_vec_s16 (cpu, vn, i) + > aarch64_get_vec_s16 (cpu, vm, i) + ? aarch64_get_vec_s16 (cpu, vn, i) + : aarch64_get_vec_s16 (cpu, vm, i)); + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_s32 (cpu, vd, i, + aarch64_get_vec_s32 (cpu, vn, i) + > aarch64_get_vec_s32 (cpu, vm, i) + ? aarch64_get_vec_s32 (cpu, vn, i) + : aarch64_get_vec_s32 (cpu, vm, i)); + return; + + default: + case 3: + HALT_UNALLOC; + } + } +} + +static void +do_vec_min (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full/half selector + instr[29] = SMIN (0) / UMIN (1) + instr[28,24] = 0 1110 + instr[23,22] = size: 00=> 8-bit, 01=> 16-bit, 10=> 32-bit + instr[21] = 1 + instr[20,16] = Vn + instr[15,10] = 0110 11 + instr[9,5] = Vm + instr[4.0] = Vd. */ + + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (28, 24, 0x0E); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x1B); + + if (uimm (aarch64_get_instr (cpu), 29, 29)) + { + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, + aarch64_get_vec_u8 (cpu, vn, i) + < aarch64_get_vec_u8 (cpu, vm, i) + ? aarch64_get_vec_u8 (cpu, vn, i) + : aarch64_get_vec_u8 (cpu, vm, i)); + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_u16 (cpu, vd, i, + aarch64_get_vec_u16 (cpu, vn, i) + < aarch64_get_vec_u16 (cpu, vm, i) + ? aarch64_get_vec_u16 (cpu, vn, i) + : aarch64_get_vec_u16 (cpu, vm, i)); + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, + aarch64_get_vec_u32 (cpu, vn, i) + < aarch64_get_vec_u32 (cpu, vm, i) + ? aarch64_get_vec_u32 (cpu, vn, i) + : aarch64_get_vec_u32 (cpu, vm, i)); + return; + + default: + case 3: + HALT_UNALLOC; + } + } + else + { + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_s8 (cpu, vd, i, + aarch64_get_vec_s8 (cpu, vn, i) + < aarch64_get_vec_s8 (cpu, vm, i) + ? aarch64_get_vec_s8 (cpu, vn, i) + : aarch64_get_vec_s8 (cpu, vm, i)); + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_s16 (cpu, vd, i, + aarch64_get_vec_s16 (cpu, vn, i) + < aarch64_get_vec_s16 (cpu, vm, i) + ? aarch64_get_vec_s16 (cpu, vn, i) + : aarch64_get_vec_s16 (cpu, vm, i)); + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_s32 (cpu, vd, i, + aarch64_get_vec_s32 (cpu, vn, i) + < aarch64_get_vec_s32 (cpu, vm, i) + ? aarch64_get_vec_s32 (cpu, vn, i) + : aarch64_get_vec_s32 (cpu, vm, i)); + return; + + default: + case 3: + HALT_UNALLOC; + } + } +} + +static void +do_vec_sub_long (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = lower (0) / upper (1) + instr[29] = signed (0) / unsigned (1) + instr[28,24] = 0 1110 + instr[23,22] = size: bytes (00), half (01), word (10) + instr[21] = 1 + insrt[20,16] = Vm + instr[15,10] = 0010 00 + instr[9,5] = Vn + instr[4,0] = V dest. */ + + unsigned size = uimm (aarch64_get_instr (cpu), 23, 22); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned bias = 0; + unsigned i; + + NYI_assert (28, 24, 0x0E); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x08); + + if (size == 3) + HALT_UNALLOC; + + switch (uimm (aarch64_get_instr (cpu), 30, 29)) + { + case 2: /* SSUBL2. */ + bias = 2; + case 0: /* SSUBL. */ + switch (size) + { + case 0: + bias *= 3; + for (i = 0; i < 8; i++) + aarch64_set_vec_s16 (cpu, vd, i, + aarch64_get_vec_s8 (cpu, vn, i + bias) + - aarch64_get_vec_s8 (cpu, vm, i + bias)); + break; + + case 1: + bias *= 2; + for (i = 0; i < 4; i++) + aarch64_set_vec_s32 (cpu, vd, i, + aarch64_get_vec_s16 (cpu, vn, i + bias) + - aarch64_get_vec_s16 (cpu, vm, i + bias)); + break; + + case 2: + for (i = 0; i < 2; i++) + aarch64_set_vec_s64 (cpu, vd, i, + aarch64_get_vec_s32 (cpu, vn, i + bias) + - aarch64_get_vec_s32 (cpu, vm, i + bias)); + break; + + default: + HALT_UNALLOC; + } + break; + + case 3: /* USUBL2. */ + bias = 2; + case 1: /* USUBL. */ + switch (size) + { + case 0: + bias *= 3; + for (i = 0; i < 8; i++) + aarch64_set_vec_u16 (cpu, vd, i, + aarch64_get_vec_u8 (cpu, vn, i + bias) + - aarch64_get_vec_u8 (cpu, vm, i + bias)); + break; + + case 1: + bias *= 2; + for (i = 0; i < 4; i++) + aarch64_set_vec_u32 (cpu, vd, i, + aarch64_get_vec_u16 (cpu, vn, i + bias) + - aarch64_get_vec_u16 (cpu, vm, i + bias)); + break; + + case 2: + for (i = 0; i < 2; i++) + aarch64_set_vec_u64 (cpu, vd, i, + aarch64_get_vec_u32 (cpu, vn, i + bias) + - aarch64_get_vec_u32 (cpu, vm, i + bias)); + break; + + default: + HALT_UNALLOC; + } + break; + } +} + +#define DO_ADDP(FN) \ + do \ + { \ + for (i = 0; i < range; i++) \ + { \ + aarch64_set_vec_##FN (cpu, vd, i, \ + aarch64_get_vec_##FN (cpu, vn, i * 2) \ + + aarch64_get_vec_##FN (cpu, vn, i * 2 + 1)); \ + aarch64_set_vec_##FN (cpu, vd, i + range, \ + aarch64_get_vec_##FN (cpu, vm, i * 2) \ + + aarch64_get_vec_##FN (cpu, vm, i * 2 + 1)); \ + } \ + } \ + while (0) + +static void +do_vec_ADDP (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,24] = 00 1110 + instr[23,22] = size: bytes (00), half (01), word (10), long (11) + instr[21] = 1 + insrt[20,16] = Vm + instr[15,10] = 1011 11 + instr[9,5] = Vn + instr[4,0] = V dest. */ + + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned size = uimm (aarch64_get_instr (cpu), 23, 22); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i, range; + + NYI_assert (29, 24, 0x0E); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x2F); + + switch (size) + { + case 0: + range = full ? 8 : 4; + DO_ADDP (u8); + return; + + case 1: + range = full ? 4 : 2; + DO_ADDP (u16); + return; + + case 2: + range = full ? 2 : 1; + DO_ADDP (u32); + return; + + case 3: + if (! full) + HALT_UNALLOC; + range = 1; + DO_ADDP (u64); + return; + + default: + HALT_NYI; + } +} + +static void +do_vec_UMOV (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = 32-bit(0)/64-bit(1) + instr[29,21] = 00 1110 000 + insrt[20,16] = size & index + instr[15,10] = 0011 11 + instr[9,5] = V source + instr[4,0] = R dest. */ + + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned index; + + NYI_assert (29, 21, 0x070); + NYI_assert (15, 10, 0x0F); + + if (uimm (aarch64_get_instr (cpu), 16, 16)) + { + /* Byte transfer. */ + index = uimm (aarch64_get_instr (cpu), 20, 17); + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_vec_u8 (cpu, vs, index)); + } + else if (uimm (aarch64_get_instr (cpu), 17, 17)) + { + index = uimm (aarch64_get_instr (cpu), 20, 18); + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_vec_u16 (cpu, vs, index)); + } + else if (uimm (aarch64_get_instr (cpu), 18, 18)) + { + index = uimm (aarch64_get_instr (cpu), 20, 19); + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_vec_u32 (cpu, vs, index)); + } + else + { + if (uimm (aarch64_get_instr (cpu), 30, 30) != 1) + HALT_UNALLOC; + + index = uimm (aarch64_get_instr (cpu), 20, 20); + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_vec_u64 (cpu, vs, index)); + } +} + +static void +do_vec_FABS (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,23] = 00 1110 1 + instr[22] = float(0)/double(1) + instr[21,16] = 10 0000 + instr[15,10] = 1111 10 + instr[9,5] = Vn + instr[4,0] = Vd. */ + + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned i; + + NYI_assert (29, 23, 0x1D); + NYI_assert (21, 10, 0x83E); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + if (! full) + HALT_NYI; + + for (i = 0; i < 2; i++) + aarch64_set_vec_double (cpu, vd, i, + fabs (aarch64_get_vec_double (cpu, vn, i))); + } + else + { + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_float (cpu, vd, i, + fabsf (aarch64_get_vec_float (cpu, vn, i))); + } +} + +static void +do_vec_FCVTZS (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half (0) / all (1) + instr[29,23] = 00 1110 1 + instr[22] = single (0) / double (1) + instr[21,10] = 10 0001 1011 10 + instr[9,5] = Rn + instr[4,0] = Rd. */ + + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned i; + + NYI_assert (31, 31, 0); + NYI_assert (29, 23, 0x1D); + NYI_assert (21, 10, 0x86E); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + if (! full) + HALT_UNALLOC; + + for (i = 0; i < 2; i++) + aarch64_set_vec_s64 (cpu, rd, i, + (int64_t) aarch64_get_vec_double (cpu, rn, i)); + } + else + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_s32 (cpu, rd, i, + (int32_t) aarch64_get_vec_float (cpu, rn, i)); +} + +static void +do_vec_op1 (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half/full + instr[29,24] = 00 1110 + instr[23,21] = ??? + instr[20,16] = Vm + instr[15,10] = sub-opcode + instr[9,5] = Vn + instr[4,0] = Vd */ + NYI_assert (29, 24, 0x0E); + + if (uimm (aarch64_get_instr (cpu), 21, 21) == 0) + { + if (uimm (aarch64_get_instr (cpu), 23, 22) == 0) + { + if (uimm (aarch64_get_instr (cpu), 30, 30) == 1 + && uimm (aarch64_get_instr (cpu), 17, 14) == 0 + && uimm (aarch64_get_instr (cpu), 12, 10) == 7) + return do_vec_ins_2 (cpu); + + switch (uimm (aarch64_get_instr (cpu), 15, 10)) + { + case 0x01: do_vec_DUP_vector_into_vector (cpu); return; + case 0x03: do_vec_DUP_scalar_into_vector (cpu); return; + case 0x07: do_vec_INS (cpu); return; + case 0x0A: do_vec_TRN (cpu); return; + + case 0x0F: + if (uimm (aarch64_get_instr (cpu), 17, 16) == 0) + { + do_vec_MOV_into_scalar (cpu); + return; + } + break; + + case 0x00: + case 0x08: + case 0x10: + case 0x18: + do_vec_TBL (cpu); return; + + case 0x06: + case 0x16: + do_vec_UZP (cpu); return; + + case 0x0E: + case 0x1E: + do_vec_ZIP (cpu); return; + + default: + HALT_NYI; + } + } + + switch (uimm (aarch64_get_instr (cpu), 13, 10)) + { + case 0x6: do_vec_UZP (cpu); return; + case 0xE: do_vec_ZIP (cpu); return; + case 0xA: do_vec_TRN (cpu); return; + case 0xF: do_vec_UMOV (cpu); return; + default: HALT_NYI; + } + } + + switch (uimm (aarch64_get_instr (cpu), 15, 10)) + { + case 0x07: + switch (uimm (aarch64_get_instr (cpu), 23, 21)) + { + case 1: do_vec_AND (cpu); return; + case 3: do_vec_BIC (cpu); return; + case 5: do_vec_ORR (cpu); return; + case 7: do_vec_ORN (cpu); return; + default: HALT_NYI; + } + + case 0x08: do_vec_sub_long (cpu); return; + case 0x0a: do_vec_XTN (cpu); return; + case 0x11: do_vec_SSHL (cpu); return; + case 0x19: do_vec_max (cpu); return; + case 0x1B: do_vec_min (cpu); return; + case 0x21: do_vec_add (cpu); return; + case 0x25: do_vec_MLA (cpu); return; + case 0x27: do_vec_mul (cpu); return; + case 0x2F: do_vec_ADDP (cpu); return; + case 0x30: do_vec_mull (cpu); return; + case 0x33: do_vec_FMLA (cpu); return; + case 0x35: do_vec_fadd (cpu); return; + + case 0x2E: + switch (uimm (aarch64_get_instr (cpu), 20, 16)) + { + case 0x00: do_vec_ABS (cpu); return; + case 0x01: do_vec_FCVTZS (cpu); return; + case 0x11: do_vec_ADDV (cpu); return; + default: HALT_NYI; + } + + case 0x31: + case 0x3B: + do_vec_Fminmax (cpu); return; + + case 0x0D: + case 0x0F: + case 0x22: + case 0x23: + case 0x26: + case 0x2A: + case 0x32: + case 0x36: + case 0x39: + case 0x3A: + do_vec_compare (cpu); return; + + case 0x3E: + do_vec_FABS (cpu); return; + + default: + HALT_NYI; + } +} + +static void +do_vec_xtl (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30,29] = SXTL (00), UXTL (01), SXTL2 (10), UXTL2 (11) + instr[28,22] = 0 1111 00 + instr[21,16] = size & shift (USHLL, SSHLL, USHLL2, SSHLL2) + instr[15,10] = 1010 01 + instr[9,5] = V source + instr[4,0] = V dest. */ + + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i, shift, bias = 0; + + NYI_assert (28, 22, 0x3C); + NYI_assert (15, 10, 0x29); + + switch (uimm (aarch64_get_instr (cpu), 30, 29)) + { + case 2: /* SXTL2, SSHLL2. */ + bias = 2; + case 0: /* SXTL, SSHLL. */ + if (uimm (aarch64_get_instr (cpu), 21, 21)) + { + shift = uimm (aarch64_get_instr (cpu), 20, 16); + aarch64_set_vec_s64 + (cpu, vd, 0, aarch64_get_vec_s32 (cpu, vs, bias) << shift); + aarch64_set_vec_s64 + (cpu, vd, 1, aarch64_get_vec_s32 (cpu, vs, bias + 1) << shift); + } + else if (uimm (aarch64_get_instr (cpu), 20, 20)) + { + shift = uimm (aarch64_get_instr (cpu), 19, 16); + bias *= 2; + for (i = 0; i < 4; i++) + aarch64_set_vec_s32 + (cpu, vd, i, aarch64_get_vec_s16 (cpu, vs, i + bias) << shift); + } + else + { + NYI_assert (19, 19, 1); + + shift = uimm (aarch64_get_instr (cpu), 18, 16); + bias *= 3; + for (i = 0; i < 8; i++) + aarch64_set_vec_s16 + (cpu, vd, i, aarch64_get_vec_s8 (cpu, vs, i + bias) << shift); + } + return; + + case 3: /* UXTL2, USHLL2. */ + bias = 2; + case 1: /* UXTL, USHLL. */ + if (uimm (aarch64_get_instr (cpu), 21, 21)) + { + shift = uimm (aarch64_get_instr (cpu), 20, 16); + aarch64_set_vec_u64 + (cpu, vd, 0, aarch64_get_vec_u32 (cpu, vs, bias) << shift); + aarch64_set_vec_u64 + (cpu, vd, 1, aarch64_get_vec_u32 (cpu, vs, bias + 1) << shift); + } + else if (uimm (aarch64_get_instr (cpu), 20, 20)) + { + shift = uimm (aarch64_get_instr (cpu), 19, 16); + bias *= 2; + for (i = 0; i < 4; i++) + aarch64_set_vec_u32 + (cpu, vd, i, aarch64_get_vec_u16 (cpu, vs, i + bias) << shift); + } + else + { + NYI_assert (19, 19, 1); + + shift = uimm (aarch64_get_instr (cpu), 18, 16); + bias *= 3; + for (i = 0; i < 8; i++) + aarch64_set_vec_u16 + (cpu, vd, i, aarch64_get_vec_u8 (cpu, vs, i + bias) << shift); + } + return; + + default: + HALT_NYI; + } +} + +static void +do_vec_SHL (sim_cpu *cpu) +{ + /* instr [31] = 0 + instr [30] = half(0)/full(1) + instr [29,23] = 001 1110 + instr [22,16] = size and shift amount + instr [15,10] = 01 0101 + instr [9, 5] = Vs + instr [4, 0] = Vd. */ + + int shift; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (29, 23, 0x1E); + NYI_assert (15, 10, 0x15); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + shift = uimm (aarch64_get_instr (cpu), 21, 16) - 1; + + if (full == 0) + HALT_UNALLOC; + + for (i = 0; i < 2; i++) + { + uint64_t val = aarch64_get_vec_u64 (cpu, vs, i); + aarch64_set_vec_u64 (cpu, vd, i, val << shift); + } + + return; + } + + if (uimm (aarch64_get_instr (cpu), 21, 21)) + { + shift = uimm (aarch64_get_instr (cpu), 20, 16) - 1; + + for (i = 0; i < (full ? 4 : 2); i++) + { + uint32_t val = aarch64_get_vec_u32 (cpu, vs, i); + aarch64_set_vec_u32 (cpu, vd, i, val << shift); + } + + return; + } + + if (uimm (aarch64_get_instr (cpu), 20, 20)) + { + shift = uimm (aarch64_get_instr (cpu), 19, 16) - 1; + + for (i = 0; i < (full ? 8 : 4); i++) + { + uint16_t val = aarch64_get_vec_u16 (cpu, vs, i); + aarch64_set_vec_u16 (cpu, vd, i, val << shift); + } + + return; + } + + if (uimm (aarch64_get_instr (cpu), 19, 19) == 0) + HALT_UNALLOC; + + shift = uimm (aarch64_get_instr (cpu), 18, 16) - 1; + + for (i = 0; i < (full ? 16 : 8); i++) + { + uint8_t val = aarch64_get_vec_u8 (cpu, vs, i); + aarch64_set_vec_u8 (cpu, vd, i, val << shift); + } +} + +static void +do_vec_SSHR_USHR (sim_cpu *cpu) +{ + /* instr [31] = 0 + instr [30] = half(0)/full(1) + instr [29] = signed(0)/unsigned(1) + instr [28,23] = 01 1110 + instr [22,16] = size and shift amount + instr [15,10] = 0000 01 + instr [9, 5] = Vs + instr [4, 0] = Vd. */ + + int shift; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + int sign = uimm (aarch64_get_instr (cpu), 29, 29); + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (28, 23, 0x1E); + NYI_assert (15, 10, 0x01); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + shift = uimm (aarch64_get_instr (cpu), 21, 16); + + if (full == 0) + HALT_UNALLOC; + + if (sign) + for (i = 0; i < 2; i++) + { + int64_t val = aarch64_get_vec_s64 (cpu, vs, i); + aarch64_set_vec_s64 (cpu, vd, i, val >> shift); + } + else + for (i = 0; i < 2; i++) + { + uint64_t val = aarch64_get_vec_u64 (cpu, vs, i); + aarch64_set_vec_u64 (cpu, vd, i, val >> shift); + } + + return; + } + + if (uimm (aarch64_get_instr (cpu), 21, 21)) + { + shift = uimm (aarch64_get_instr (cpu), 20, 16); + + if (sign) + for (i = 0; i < (full ? 4 : 2); i++) + { + int32_t val = aarch64_get_vec_s32 (cpu, vs, i); + aarch64_set_vec_s32 (cpu, vd, i, val >> shift); + } + else + for (i = 0; i < (full ? 4 : 2); i++) + { + uint32_t val = aarch64_get_vec_u32 (cpu, vs, i); + aarch64_set_vec_u32 (cpu, vd, i, val >> shift); + } + + return; + } + + if (uimm (aarch64_get_instr (cpu), 20, 20)) + { + shift = uimm (aarch64_get_instr (cpu), 19, 16); + + if (sign) + for (i = 0; i < (full ? 8 : 4); i++) + { + int16_t val = aarch64_get_vec_s16 (cpu, vs, i); + aarch64_set_vec_s16 (cpu, vd, i, val >> shift); + } + else + for (i = 0; i < (full ? 8 : 4); i++) + { + uint16_t val = aarch64_get_vec_u16 (cpu, vs, i); + aarch64_set_vec_u16 (cpu, vd, i, val >> shift); + } + + return; + } + + if (uimm (aarch64_get_instr (cpu), 19, 19) == 0) + HALT_UNALLOC; + + shift = uimm (aarch64_get_instr (cpu), 18, 16); + + if (sign) + for (i = 0; i < (full ? 16 : 8); i++) + { + int8_t val = aarch64_get_vec_s8 (cpu, vs, i); + aarch64_set_vec_s8 (cpu, vd, i, val >> shift); + } + else + for (i = 0; i < (full ? 16 : 8); i++) + { + uint8_t val = aarch64_get_vec_u8 (cpu, vs, i); + aarch64_set_vec_u8 (cpu, vd, i, val >> shift); + } +} + +static void +do_vec_op2 (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half/full + instr[29,24] = 00 1111 + instr[23] = ? + instr[22,16] = element size & index + instr[15,10] = sub-opcode + instr[9,5] = Vm + instr[4.0] = Vd */ + + NYI_assert (29, 24, 0x0F); + + if (uimm (aarch64_get_instr (cpu), 23, 23) != 0) + HALT_NYI; + + switch (uimm (aarch64_get_instr (cpu), 15, 10)) + { + case 0x01: do_vec_SSHR_USHR (cpu); return; + case 0x15: do_vec_SHL (cpu); return; + case 0x29: do_vec_xtl (cpu); return; + default: HALT_NYI; + } +} + +static void +do_vec_neg (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full(1)/half(0) + instr[29,24] = 10 1110 + instr[23,22] = size: byte(00), half (01), word (10), long (11) + instr[21,10] = 1000 0010 1110 + instr[9,5] = Vs + instr[4,0] = Vd */ + + int full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (29, 24, 0x2E); + NYI_assert (21, 10, 0x82E); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_s8 (cpu, vd, i, - aarch64_get_vec_s8 (cpu, vs, i)); + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_s16 (cpu, vd, i, - aarch64_get_vec_s16 (cpu, vs, i)); + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_s32 (cpu, vd, i, - aarch64_get_vec_s32 (cpu, vs, i)); + return; + + case 3: + if (! full) + HALT_NYI; + for (i = 0; i < 2; i++) + aarch64_set_vec_s64 (cpu, vd, i, - aarch64_get_vec_s64 (cpu, vs, i)); + return; + + default: + HALT_UNREACHABLE; + } +} + +static void +do_vec_sqrt (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = full(1)/half(0) + instr[29,23] = 101 1101 + instr[22] = single(0)/double(1) + instr[21,10] = 1000 0111 1110 + instr[9,5] = Vs + instr[4,0] = Vd. */ + + int full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (29, 23, 0x5B); + NYI_assert (21, 10, 0x87E); + + if (uimm (aarch64_get_instr (cpu), 22, 22) == 0) + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_float (cpu, vd, i, + sqrtf (aarch64_get_vec_float (cpu, vs, i))); + else + for (i = 0; i < 2; i++) + aarch64_set_vec_double (cpu, vd, i, + sqrt (aarch64_get_vec_double (cpu, vs, i))); +} + +static void +do_vec_mls_indexed (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,24] = 10 1111 + instr[23,22] = 16-bit(01)/32-bit(10) + instr[21,20+11] = index (if 16-bit) + instr[21+11] = index (if 32-bit) + instr[20,16] = Vm + instr[15,12] = 0100 + instr[11] = part of index + instr[10] = 0 + instr[9,5] = Vs + instr[4,0] = Vd. */ + + int full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned i; + + NYI_assert (15, 12, 4); + NYI_assert (10, 10, 0); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 1: + { + unsigned elem; + uint32_t val; + + if (vm > 15) + HALT_NYI; + + elem = (uimm (aarch64_get_instr (cpu), 21, 20) << 1) + | uimm (aarch64_get_instr (cpu), 11, 11); + val = aarch64_get_vec_u16 (cpu, vm, elem); + + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_u32 (cpu, vd, i, + aarch64_get_vec_u32 (cpu, vd, i) - + (aarch64_get_vec_u32 (cpu, vs, i) * val)); + return; + } + + case 2: + { + unsigned elem = (uimm (aarch64_get_instr (cpu), 21, 21) << 1) + | uimm (aarch64_get_instr (cpu), 11, 11); + uint64_t val = aarch64_get_vec_u32 (cpu, vm, elem); + + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u64 (cpu, vd, i, + aarch64_get_vec_u64 (cpu, vd, i) - + (aarch64_get_vec_u64 (cpu, vs, i) * val)); + return; + } + + case 0: + case 3: + default: + HALT_NYI; + } +} + +static void +do_vec_SUB (sim_cpu *cpu) +{ + /* instr [31] = 0 + instr [30] = half(0)/full(1) + instr [29,24] = 10 1110 + instr [23,22] = size: byte(00, half(01), word (10), long (11) + instr [21] = 1 + instr [20,16] = Vm + instr [15,10] = 10 0001 + instr [9, 5] = Vn + instr [4, 0] = Vd. */ + + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (29, 24, 0x2E); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x21); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_s8 (cpu, vd, i, + aarch64_get_vec_s8 (cpu, vn, i) + - aarch64_get_vec_s8 (cpu, vm, i)); + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_s16 (cpu, vd, i, + aarch64_get_vec_s16 (cpu, vn, i) + - aarch64_get_vec_s16 (cpu, vm, i)); + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_s32 (cpu, vd, i, + aarch64_get_vec_s32 (cpu, vn, i) + - aarch64_get_vec_s32 (cpu, vm, i)); + return; + + case 3: + if (full == 0) + HALT_UNALLOC; + + for (i = 0; i < 2; i++) + aarch64_set_vec_s64 (cpu, vd, i, + aarch64_get_vec_s64 (cpu, vn, i) + - aarch64_get_vec_s64 (cpu, vm, i)); + return; + + default: + HALT_UNREACHABLE; + } +} + +static void +do_vec_MLS (sim_cpu *cpu) +{ + /* instr [31] = 0 + instr [30] = half(0)/full(1) + instr [29,24] = 10 1110 + instr [23,22] = size: byte(00, half(01), word (10) + instr [21] = 1 + instr [20,16] = Vm + instr [15,10] = 10 0101 + instr [9, 5] = Vn + instr [4, 0] = Vd. */ + + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (29, 24, 0x2E); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x25); + + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, + (aarch64_get_vec_u8 (cpu, vn, i) + * aarch64_get_vec_u8 (cpu, vm, i)) + - aarch64_get_vec_u8 (cpu, vd, i)); + return; + + case 1: + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_u16 (cpu, vd, i, + (aarch64_get_vec_u16 (cpu, vn, i) + * aarch64_get_vec_u16 (cpu, vm, i)) + - aarch64_get_vec_u16 (cpu, vd, i)); + return; + + case 2: + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, + (aarch64_get_vec_u32 (cpu, vn, i) + * aarch64_get_vec_u32 (cpu, vm, i)) + - aarch64_get_vec_u32 (cpu, vd, i)); + return; + + default: + HALT_UNALLOC; + } +} + +static void +do_vec_FDIV (sim_cpu *cpu) +{ + /* instr [31] = 0 + instr [30] = half(0)/full(1) + instr [29,23] = 10 1110 0 + instr [22] = float()/double(1) + instr [21] = 1 + instr [20,16] = Vm + instr [15,10] = 1111 11 + instr [9, 5] = Vn + instr [4, 0] = Vd. */ + + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (29, 23, 0x5C); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x3F); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + if (! full) + HALT_UNALLOC; + + for (i = 0; i < 2; i++) + aarch64_set_vec_double (cpu, vd, i, + aarch64_get_vec_double (cpu, vn, i) + / aarch64_get_vec_double (cpu, vm, i)); + } + else + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_float (cpu, vd, i, + aarch64_get_vec_float (cpu, vn, i) + / aarch64_get_vec_float (cpu, vm, i)); +} + +static void +do_vec_FMUL (sim_cpu *cpu) +{ + /* instr [31] = 0 + instr [30] = half(0)/full(1) + instr [29,23] = 10 1110 0 + instr [22] = float(0)/double(1) + instr [21] = 1 + instr [20,16] = Vm + instr [15,10] = 1101 11 + instr [9, 5] = Vn + instr [4, 0] = Vd. */ + + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + NYI_assert (29, 23, 0x5C); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x37); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + if (! full) + HALT_UNALLOC; + + for (i = 0; i < 2; i++) + aarch64_set_vec_double (cpu, vd, i, + aarch64_get_vec_double (cpu, vn, i) + * aarch64_get_vec_double (cpu, vm, i)); + } + else + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_float (cpu, vd, i, + aarch64_get_vec_float (cpu, vn, i) + * aarch64_get_vec_float (cpu, vm, i)); +} + +static void +do_vec_FADDP (sim_cpu *cpu) +{ + /* instr [31] = 0 + instr [30] = half(0)/full(1) + instr [29,23] = 10 1110 0 + instr [22] = float(0)/double(1) + instr [21] = 1 + instr [20,16] = Vm + instr [15,10] = 1101 01 + instr [9, 5] = Vn + instr [4, 0] = Vd. */ + + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (29, 23, 0x5C); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x35); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + if (! full) + HALT_UNALLOC; + + aarch64_set_vec_double (cpu, vd, 0, aarch64_get_vec_double (cpu, vn, 0) + + aarch64_get_vec_double (cpu, vn, 1)); + aarch64_set_vec_double (cpu, vd, 1, aarch64_get_vec_double (cpu, vm, 0) + + aarch64_get_vec_double (cpu, vm, 1)); + } + else + { + aarch64_set_vec_float (cpu, vd, 0, aarch64_get_vec_float (cpu, vn, 0) + + aarch64_get_vec_float (cpu, vn, 1)); + if (full) + aarch64_set_vec_float (cpu, vd, 1, aarch64_get_vec_float (cpu, vn, 2) + + aarch64_get_vec_float (cpu, vn, 3)); + aarch64_set_vec_float (cpu, vd, full ? 2 : 1, + aarch64_get_vec_float (cpu, vm, 0) + + aarch64_get_vec_float (cpu, vm, 1)); + if (full) + aarch64_set_vec_float (cpu, vd, 3, + aarch64_get_vec_float (cpu, vm, 2) + + aarch64_get_vec_float (cpu, vm, 3)); + } +} + +static void +do_vec_FSQRT (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half(0)/full(1) + instr[29,23] = 10 1110 1 + instr[22] = single(0)/double(1) + instr[21,10] = 10 0001 1111 10 + instr[9,5] = Vsrc + instr[4,0] = Vdest. */ + + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + int i; + + NYI_assert (29, 23, 0x5D); + NYI_assert (21, 10, 0x87E); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + if (! full) + HALT_UNALLOC; + + for (i = 0; i < 2; i++) + aarch64_set_vec_double (cpu, vd, i, + sqrt (aarch64_get_vec_double (cpu, vn, i))); + } + else + { + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_float (cpu, vd, i, + sqrtf (aarch64_get_vec_float (cpu, vn, i))); + } +} + +static void +do_vec_FNEG (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half (0)/full (1) + instr[29,23] = 10 1110 1 + instr[22] = single (0)/double (1) + instr[21,10] = 10 0000 1111 10 + instr[9,5] = Vsrc + instr[4,0] = Vdest. */ + + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + int i; + + NYI_assert (29, 23, 0x5D); + NYI_assert (21, 10, 0x83E); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + if (! full) + HALT_UNALLOC; + + for (i = 0; i < 2; i++) + aarch64_set_vec_double (cpu, vd, i, + - aarch64_get_vec_double (cpu, vn, i)); + } + else + { + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_float (cpu, vd, i, + - aarch64_get_vec_float (cpu, vn, i)); + } +} + +static void +do_vec_NOT (sim_cpu *cpu) +{ + /* instr[31] = 0 + instr[30] = half (0)/full (1) + instr[29,21] = 10 1110 001 + instr[20,16] = 0 0000 + instr[15,10] = 0101 10 + instr[9,5] = Vn + instr[4.0] = Vd. */ + + unsigned vn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + int full = uimm (aarch64_get_instr (cpu), 30, 30); + + NYI_assert (29, 10, 0xB8816); + + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, ~ aarch64_get_vec_u8 (cpu, vn, i)); +} + +static void +do_vec_MOV_element (sim_cpu *cpu) +{ + /* instr[31,21] = 0110 1110 000 + instr[20,16] = size & dest index + instr[15] = 0 + instr[14,11] = source index + instr[10] = 1 + instr[9,5] = Vs + instr[4.0] = Vd. */ + + unsigned vs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned src_index; + unsigned dst_index; + + NYI_assert (31, 21, 0x370); + NYI_assert (15, 15, 0); + NYI_assert (10, 10, 1); + + if (uimm (aarch64_get_instr (cpu), 16, 16)) + { + /* Move a byte. */ + src_index = uimm (aarch64_get_instr (cpu), 14, 11); + dst_index = uimm (aarch64_get_instr (cpu), 20, 17); + aarch64_set_vec_u8 (cpu, vd, dst_index, + aarch64_get_vec_u8 (cpu, vs, src_index)); + } + else if (uimm (aarch64_get_instr (cpu), 17, 17)) + { + /* Move 16-bits. */ + NYI_assert (11, 11, 0); + src_index = uimm (aarch64_get_instr (cpu), 14, 12); + dst_index = uimm (aarch64_get_instr (cpu), 20, 18); + aarch64_set_vec_u16 (cpu, vd, dst_index, + aarch64_get_vec_u16 (cpu, vs, src_index)); + } + else if (uimm (aarch64_get_instr (cpu), 18, 18)) + { + /* Move 32-bits. */ + NYI_assert (12, 11, 0); + src_index = uimm (aarch64_get_instr (cpu), 14, 13); + dst_index = uimm (aarch64_get_instr (cpu), 20, 19); + aarch64_set_vec_u32 (cpu, vd, dst_index, + aarch64_get_vec_u32 (cpu, vs, src_index)); + } + else + { + NYI_assert (19, 19, 1); + NYI_assert (13, 11, 0); + src_index = uimm (aarch64_get_instr (cpu), 14, 14); + dst_index = uimm (aarch64_get_instr (cpu), 20, 20); + aarch64_set_vec_u64 (cpu, vd, dst_index, + aarch64_get_vec_u64 (cpu, vs, src_index)); + } +} + +static void +dexAdvSIMD0 (sim_cpu *cpu) +{ + /* instr [28,25] = 0 111. */ + if ( uimm (aarch64_get_instr (cpu), 15, 10) == 0x07 + && (uimm (aarch64_get_instr (cpu), 9, 5) == + uimm (aarch64_get_instr (cpu), 20, 16))) + { + if (uimm (aarch64_get_instr (cpu), 31, 21) == 0x075 + || uimm (aarch64_get_instr (cpu), 31, 21) == 0x275) + { + do_vec_MOV_whole_vector (cpu); + return; + } + } + + if (uimm (aarch64_get_instr (cpu), 29, 19) == 0x1E0) + { + do_vec_MOV_immediate (cpu); + return; + } + + if (uimm (aarch64_get_instr (cpu), 29, 19) == 0x5E0) + { + do_vec_MVNI (cpu); + return; + } + + if (uimm (aarch64_get_instr (cpu), 29, 19) == 0x1C0 + || uimm (aarch64_get_instr (cpu), 29, 19) == 0x1C1) + { + if (uimm (aarch64_get_instr (cpu), 15, 10) == 0x03) + { + do_vec_DUP_scalar_into_vector (cpu); + return; + } + } + + switch (uimm (aarch64_get_instr (cpu), 29, 24)) + { + case 0x0E: do_vec_op1 (cpu); return; + case 0x0F: do_vec_op2 (cpu); return; + + case 0x2f: + switch (uimm (aarch64_get_instr (cpu), 15, 10)) + { + case 0x01: do_vec_SSHR_USHR (cpu); return; + case 0x10: + case 0x12: do_vec_mls_indexed (cpu); return; + case 0x29: do_vec_xtl (cpu); return; + default: + HALT_NYI; + } + + case 0x2E: + if (uimm (aarch64_get_instr (cpu), 21, 21) == 1) + { + switch (uimm (aarch64_get_instr (cpu), 15, 10)) + { + case 0x07: + switch (uimm (aarch64_get_instr (cpu), 23, 22)) + { + case 0: do_vec_EOR (cpu); return; + case 1: do_vec_BSL (cpu); return; + case 2: + case 3: do_vec_bit (cpu); return; + } + break; + + case 0x08: do_vec_sub_long (cpu); return; + case 0x11: do_vec_USHL (cpu); return; + case 0x16: do_vec_NOT (cpu); return; + case 0x19: do_vec_max (cpu); return; + case 0x1B: do_vec_min (cpu); return; + case 0x21: do_vec_SUB (cpu); return; + case 0x25: do_vec_MLS (cpu); return; + case 0x31: do_vec_FminmaxNMP (cpu); return; + case 0x35: do_vec_FADDP (cpu); return; + case 0x37: do_vec_FMUL (cpu); return; + case 0x3F: do_vec_FDIV (cpu); return; + + case 0x3E: + switch (uimm (aarch64_get_instr (cpu), 20, 16)) + { + case 0x00: do_vec_FNEG (cpu); return; + case 0x01: do_vec_FSQRT (cpu); return; + default: HALT_NYI; + } + + case 0x0D: + case 0x0F: + case 0x22: + case 0x23: + case 0x26: + case 0x2A: + case 0x32: + case 0x36: + case 0x39: + case 0x3A: + do_vec_compare (cpu); return; + + default: break; + } + } + + if (uimm (aarch64_get_instr (cpu), 31, 21) == 0x370) + { + do_vec_MOV_element (cpu); + return; + } + + switch (uimm (aarch64_get_instr (cpu), 21, 10)) + { + case 0x82E: do_vec_neg (cpu); return; + case 0x87E: do_vec_sqrt (cpu); return; + default: + if (uimm (aarch64_get_instr (cpu), 15, 10) == 0x30) + { + do_vec_mull (cpu); + return; + } + break; + } + break; + + default: + break; + } + + HALT_NYI; +} + +/* 3 sources. */ + +/* Float multiply add. */ +static void +fmadds (sim_cpu *cpu) +{ + unsigned sa = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sa) + + aarch64_get_FP_float (cpu, sn) + * aarch64_get_FP_float (cpu, sm)); +} + +/* Double multiply add. */ +static void +fmaddd (sim_cpu *cpu) +{ + unsigned sa = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sa) + + aarch64_get_FP_double (cpu, sn) + * aarch64_get_FP_double (cpu, sm)); +} + +/* Float multiply subtract. */ +static void +fmsubs (sim_cpu *cpu) +{ + unsigned sa = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sa) + - aarch64_get_FP_float (cpu, sn) + * aarch64_get_FP_float (cpu, sm)); +} + +/* Double multiply subtract. */ +static void +fmsubd (sim_cpu *cpu) +{ + unsigned sa = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sa) + - aarch64_get_FP_double (cpu, sn) + * aarch64_get_FP_double (cpu, sm)); +} + +/* Float negative multiply add. */ +static void +fnmadds (sim_cpu *cpu) +{ + unsigned sa = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, sd, - aarch64_get_FP_float (cpu, sa) + + (- aarch64_get_FP_float (cpu, sn)) + * aarch64_get_FP_float (cpu, sm)); +} + +/* Double negative multiply add. */ +static void +fnmaddd (sim_cpu *cpu) +{ + unsigned sa = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, sd, - aarch64_get_FP_double (cpu, sa) + + (- aarch64_get_FP_double (cpu, sn)) + * aarch64_get_FP_double (cpu, sm)); +} + +/* Float negative multiply subtract. */ +static void +fnmsubs (sim_cpu *cpu) +{ + unsigned sa = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, sd, - aarch64_get_FP_float (cpu, sa) + + aarch64_get_FP_float (cpu, sn) + * aarch64_get_FP_float (cpu, sm)); +} + +/* Double negative multiply subtract. */ +static void +fnmsubd (sim_cpu *cpu) +{ + unsigned sa = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, sd, - aarch64_get_FP_double (cpu, sa) + + aarch64_get_FP_double (cpu, sn) + * aarch64_get_FP_double (cpu, sm)); +} + +static void +dexSimpleFPDataProc3Source (sim_cpu *cpu) +{ + /* instr[31] ==> M : 0 ==> OK, 1 ==> UNALLOC + instr[30] = 0 + instr[29] ==> S : 0 ==> OK, 1 ==> UNALLOC + instr[28,25] = 1111 + instr[24] = 1 + instr[23,22] ==> type : 0 ==> single, 01 ==> double, 1x ==> UNALLOC + instr[21] ==> o1 : 0 ==> unnegated, 1 ==> negated + instr[15] ==> o2 : 0 ==> ADD, 1 ==> SUB */ + + uint32_t M_S = (uimm (aarch64_get_instr (cpu), 31, 31) << 1) + | uimm (aarch64_get_instr (cpu), 29, 29); + /* dispatch on combined type:o1:o2. */ + uint32_t dispatch = (uimm (aarch64_get_instr (cpu), 23, 21) << 1) + | uimm (aarch64_get_instr (cpu), 15, 15); + + if (M_S != 0) + HALT_UNALLOC; + + switch (dispatch) + { + case 0: fmadds (cpu); return; + case 1: fmsubs (cpu); return; + case 2: fnmadds (cpu); return; + case 3: fnmsubs (cpu); return; + case 4: fmaddd (cpu); return; + case 5: fmsubd (cpu); return; + case 6: fnmaddd (cpu); return; + case 7: fnmsubd (cpu); return; + default: + /* type > 1 is currently unallocated. */ + HALT_UNALLOC; + } +} + +static void +dexSimpleFPFixedConvert (sim_cpu *cpu) +{ + HALT_NYI; +} + +static void +dexSimpleFPCondCompare (sim_cpu *cpu) +{ + HALT_NYI; +} + +/* 2 sources. */ + +/* Float add. */ +static void +fadds (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sn) + + aarch64_get_FP_float (cpu, sm)); +} + +/* Double add. */ +static void +faddd (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sn) + + aarch64_get_FP_double (cpu, sm)); +} + +/* Float divide. */ +static void +fdivs (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sn) + / aarch64_get_FP_float (cpu, sm)); +} + +/* Double divide. */ +static void +fdivd (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sn) + / aarch64_get_FP_double (cpu, sm)); +} + +/* Float multiply. */ +static void +fmuls (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sn) + * aarch64_get_FP_float (cpu, sm)); +} + +/* Double multiply. */ +static void +fmuld (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sn) + * aarch64_get_FP_double (cpu, sm)); +} + +/* Float negate and multiply. */ +static void +fnmuls (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, sd, - (aarch64_get_FP_float (cpu, sn) + * aarch64_get_FP_float (cpu, sm))); +} + +/* Double negate and multiply. */ +static void +fnmuld (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, sd, - (aarch64_get_FP_double (cpu, sn) + * aarch64_get_FP_double (cpu, sm))); +} + +/* Float subtract. */ +static void +fsubs (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, sd, aarch64_get_FP_float (cpu, sn) + - aarch64_get_FP_float (cpu, sm)); +} + +/* Double subtract. */ +static void +fsubd (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, sd, aarch64_get_FP_double (cpu, sn) + - aarch64_get_FP_double (cpu, sm)); +} + +static void +do_FMINNM (sim_cpu *cpu) +{ + /* instr[31,23] = 0 0011 1100 + instr[22] = float(0)/double(1) + instr[21] = 1 + instr[20,16] = Sm + instr[15,10] = 01 1110 + instr[9,5] = Sn + instr[4,0] = Cpu */ + + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (31, 23, 0x03C); + NYI_assert (15, 10, 0x1E); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + aarch64_set_FP_double (cpu, sd, + dminnm (aarch64_get_FP_double (cpu, sn), + aarch64_get_FP_double (cpu, sm))); + else + aarch64_set_FP_float (cpu, sd, + fminnm (aarch64_get_FP_float (cpu, sn), + aarch64_get_FP_float (cpu, sm))); +} + +static void +do_FMAXNM (sim_cpu *cpu) +{ + /* instr[31,23] = 0 0011 1100 + instr[22] = float(0)/double(1) + instr[21] = 1 + instr[20,16] = Sm + instr[15,10] = 01 1010 + instr[9,5] = Sn + instr[4,0] = Cpu */ + + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (31, 23, 0x03C); + NYI_assert (15, 10, 0x1A); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + aarch64_set_FP_double (cpu, sd, + dmaxnm (aarch64_get_FP_double (cpu, sn), + aarch64_get_FP_double (cpu, sm))); + else + aarch64_set_FP_float (cpu, sd, + fmaxnm (aarch64_get_FP_float (cpu, sn), + aarch64_get_FP_float (cpu, sm))); +} + +static void +dexSimpleFPDataProc2Source (sim_cpu *cpu) +{ + /* instr[31] ==> M : 0 ==> OK, 1 ==> UNALLOC + instr[30] = 0 + instr[29] ==> S : 0 ==> OK, 1 ==> UNALLOC + instr[28,25] = 1111 + instr[24] = 0 + instr[23,22] ==> type : 0 ==> single, 01 ==> double, 1x ==> UNALLOC + instr[21] = 1 + instr[20,16] = Vm + instr[15,12] ==> opcode : 0000 ==> FMUL, 0001 ==> FDIV + 0010 ==> FADD, 0011 ==> FSUB, + 0100 ==> FMAX, 0101 ==> FMIN + 0110 ==> FMAXNM, 0111 ==> FMINNM + 1000 ==> FNMUL, ow ==> UNALLOC + instr[11,10] = 10 + instr[9,5] = Vn + instr[4,0] = Vd */ + + uint32_t M_S = (uimm (aarch64_get_instr (cpu), 31, 31) << 1) + | uimm (aarch64_get_instr (cpu), 29, 29); + uint32_t type = uimm (aarch64_get_instr (cpu), 23, 22); + /* Dispatch on opcode. */ + uint32_t dispatch = uimm (aarch64_get_instr (cpu), 15, 12); + + if (type > 1) + HALT_UNALLOC; + + if (M_S != 0) + HALT_UNALLOC; + + if (type) + switch (dispatch) + { + case 0: fmuld (cpu); return; + case 1: fdivd (cpu); return; + case 2: faddd (cpu); return; + case 3: fsubd (cpu); return; + case 6: do_FMAXNM (cpu); return; + case 7: do_FMINNM (cpu); return; + case 8: fnmuld (cpu); return; + + /* Have not yet implemented fmax and fmin. */ + case 4: + case 5: + HALT_NYI; + + default: + HALT_UNALLOC; + } + else /* type == 0 => floats. */ + switch (dispatch) + { + case 0: fmuls (cpu); return; + case 1: fdivs (cpu); return; + case 2: fadds (cpu); return; + case 3: fsubs (cpu); return; + case 6: do_FMAXNM (cpu); return; + case 7: do_FMINNM (cpu); return; + case 8: fnmuls (cpu); return; + + case 4: + case 5: + HALT_NYI; + + default: + HALT_UNALLOC; + } +} + +static void +dexSimpleFPCondSelect (sim_cpu *cpu) +{ + /* FCSEL + instr[31,23] = 0 0011 1100 + instr[22] = 0=>single 1=>double + instr[21] = 1 + instr[20,16] = Sm + instr[15,12] = cond + instr[11,10] = 11 + instr[9,5] = Sn + instr[4,0] = Cpu */ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + uint32_t set = testConditionCode (cpu, uimm (aarch64_get_instr (cpu), 15, 12)); + + NYI_assert (31, 23, 0x03C); + NYI_assert (11, 10, 0x3); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + aarch64_set_FP_double (cpu, sd, set ? sn : sm); + else + aarch64_set_FP_float (cpu, sd, set ? sn : sm); +} + +/* Store 32 bit unscaled signed 9 bit. */ +static void +fsturs (sim_cpu *cpu, int32_t offset) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_mem_float (cpu, aarch64_get_reg_u64 (cpu, st, 1) + offset, + aarch64_get_FP_float (cpu, rn)); +} + +/* Store 64 bit unscaled signed 9 bit. */ +static void +fsturd (sim_cpu *cpu, int32_t offset) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_mem_double (cpu, aarch64_get_reg_u64 (cpu, st, 1) + offset, + aarch64_get_FP_double (cpu, rn)); +} + +/* Store 128 bit unscaled signed 9 bit. */ +static void +fsturq (sim_cpu *cpu, int32_t offset) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + FRegister a; + + aarch64_get_FP_long_double (cpu, rn, & a); + aarch64_set_mem_long_double (cpu, + aarch64_get_reg_u64 (cpu, st, 1) + + offset, a); +} + +/* TODO FP move register. */ + +/* 32 bit fp to fp move register. */ +static void +ffmovs (sim_cpu *cpu) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, st, aarch64_get_FP_float (cpu, rn)); +} + +/* 64 bit fp to fp move register. */ +static void +ffmovd (sim_cpu *cpu) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, st, aarch64_get_FP_double (cpu, rn)); +} + +/* 32 bit GReg to Vec move register. */ +static void +fgmovs (sim_cpu *cpu) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_vec_u32 (cpu, st, 0, aarch64_get_reg_u32 (cpu, rn, NO_SP)); +} + +/* 64 bit g to fp move register. */ +static void +fgmovd (sim_cpu *cpu) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_vec_u64 (cpu, st, 0, aarch64_get_reg_u64 (cpu, rn, NO_SP)); +} + +/* 32 bit fp to g move register. */ +static void +gfmovs (sim_cpu *cpu) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, st, NO_SP, aarch64_get_vec_u32 (cpu, rn, 0)); +} + +/* 64 bit fp to g move register. */ +static void +gfmovd (sim_cpu *cpu) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, st, NO_SP, aarch64_get_vec_u64 (cpu, rn, 0)); +} + +/* FP move immediate + + These install an immediate 8 bit value in the target register + where the 8 bits comprise 1 sign bit, 4 bits of fraction and a 3 + bit exponent. */ + +static void +fmovs (sim_cpu *cpu) +{ + unsigned int sd = uimm (aarch64_get_instr (cpu), 4, 0); + uint32_t imm = uimm (aarch64_get_instr (cpu), 20, 13); + float f = fp_immediate_for_encoding_32 (imm); + + aarch64_set_FP_float (cpu, sd, f); +} + +static void +fmovd (sim_cpu *cpu) +{ + unsigned int sd = uimm (aarch64_get_instr (cpu), 4, 0); + uint32_t imm = uimm (aarch64_get_instr (cpu), 20, 13); + double d = fp_immediate_for_encoding_64 (imm); + + aarch64_set_FP_double (cpu, sd, d); +} + +static void +dexSimpleFPImmediate (sim_cpu *cpu) +{ + /* instr[31,23] == 00111100 + instr[22] == type : single(0)/double(1) + instr[21] == 1 + instr[20,13] == imm8 + instr[12,10] == 100 + instr[9,5] == imm5 : 00000 ==> PK, ow ==> UNALLOC + instr[4,0] == Rd */ + uint32_t imm5 = uimm (aarch64_get_instr (cpu), 9, 5); + + NYI_assert (31, 23, 0x3C); + + if (imm5 != 0) + HALT_UNALLOC; + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + fmovd (cpu); + else + fmovs (cpu); +} + +/* TODO specific decode and execute for group Load Store. */ + +/* TODO FP load/store single register (unscaled offset). */ + +/* TODO load 8 bit unscaled signed 9 bit. */ +/* TODO load 16 bit unscaled signed 9 bit. */ + +/* Load 32 bit unscaled signed 9 bit. */ +static void +fldurs (sim_cpu *cpu, int32_t offset) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, st, aarch64_get_mem_float + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset)); +} + +/* Load 64 bit unscaled signed 9 bit. */ +static void +fldurd (sim_cpu *cpu, int32_t offset) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, st, aarch64_get_mem_double + (cpu, aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset)); +} + +/* Load 128 bit unscaled signed 9 bit. */ +static void +fldurq (sim_cpu *cpu, int32_t offset) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int st = uimm (aarch64_get_instr (cpu), 4, 0); + FRegister a; + uint64_t addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset; + + aarch64_get_mem_long_double (cpu, addr, & a); + aarch64_set_FP_long_double (cpu, st, a); +} + +/* TODO store 8 bit unscaled signed 9 bit. */ +/* TODO store 16 bit unscaled signed 9 bit. */ + + +/* 1 source. */ + +/* Float absolute value. */ +static void +fabss (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + float value = aarch64_get_FP_float (cpu, sn); + + aarch64_set_FP_float (cpu, sd, fabsf (value)); +} + +/* Double absolute value. */ +static void +fabcpu (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + double value = aarch64_get_FP_double (cpu, sn); + + aarch64_set_FP_double (cpu, sd, fabs (value)); +} + +/* Float negative value. */ +static void +fnegs (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, sd, - aarch64_get_FP_float (cpu, sn)); +} + +/* Double negative value. */ +static void +fnegd (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, sd, - aarch64_get_FP_double (cpu, sn)); +} + +/* Float square root. */ +static void +fsqrts (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, sd, sqrt (aarch64_get_FP_float (cpu, sn))); +} + +/* Double square root. */ +static void +fsqrtd (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, sd, + sqrt (aarch64_get_FP_double (cpu, sn))); +} + +/* Convert double to float. */ +static void +fcvtds (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float (cpu, sd, (float) aarch64_get_FP_double (cpu, sn)); +} + +/* Convert float to double. */ +static void +fcvtcpu (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double (cpu, sd, (double) aarch64_get_FP_float (cpu, sn)); +} + +static void +do_FRINT (sim_cpu *cpu) +{ + /* instr[31,23] = 0001 1110 0 + instr[22] = single(0)/double(1) + instr[21,18] = 1001 + instr[17,15] = rounding mode + instr[14,10] = 10000 + instr[9,5] = source + instr[4,0] = dest */ + + float val; + unsigned rs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned int rmode = uimm (aarch64_get_instr (cpu), 17, 15); + + NYI_assert (31, 23, 0x03C); + NYI_assert (21, 18, 0x9); + NYI_assert (14, 10, 0x10); + + if (rmode == 6 || rmode == 7) + /* FIXME: Add support for rmode == 6 exactness check. */ + rmode = uimm (aarch64_get_FPSR (cpu), 23, 22); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + double val = aarch64_get_FP_double (cpu, rs); + + switch (rmode) + { + case 0: /* mode N: nearest or even. */ + { + double rval = round (val); + + if (val - rval == 0.5) + { + if (((rval / 2.0) * 2.0) != rval) + rval += 1.0; + } + + aarch64_set_FP_double (cpu, rd, round (val)); + return; + } + + case 1: /* mode P: towards +inf. */ + if (val < 0.0) + aarch64_set_FP_double (cpu, rd, trunc (val)); + else + aarch64_set_FP_double (cpu, rd, round (val)); + return; + + case 2: /* mode M: towards -inf. */ + if (val < 0.0) + aarch64_set_FP_double (cpu, rd, round (val)); + else + aarch64_set_FP_double (cpu, rd, trunc (val)); + return; + + case 3: /* mode Z: towards 0. */ + aarch64_set_FP_double (cpu, rd, trunc (val)); + return; + + case 4: /* mode A: away from 0. */ + aarch64_set_FP_double (cpu, rd, round (val)); + return; + + case 6: /* mode X: use FPCR with exactness check. */ + case 7: /* mode I: use FPCR mode. */ + HALT_NYI; + + default: + HALT_UNALLOC; + } + } + + val = aarch64_get_FP_float (cpu, rs); + + switch (rmode) + { + case 0: /* mode N: nearest or even. */ + { + float rval = roundf (val); + + if (val - rval == 0.5) + { + if (((rval / 2.0) * 2.0) != rval) + rval += 1.0; + } + + aarch64_set_FP_float (cpu, rd, rval); + return; + } + + case 1: /* mode P: towards +inf. */ + if (val < 0.0) + aarch64_set_FP_float (cpu, rd, truncf (val)); + else + aarch64_set_FP_float (cpu, rd, roundf (val)); + return; + + case 2: /* mode M: towards -inf. */ + if (val < 0.0) + aarch64_set_FP_float (cpu, rd, truncf (val)); + else + aarch64_set_FP_float (cpu, rd, roundf (val)); + return; + + case 3: /* mode Z: towards 0. */ + aarch64_set_FP_float (cpu, rd, truncf (val)); + return; + + case 4: /* mode A: away from 0. */ + aarch64_set_FP_float (cpu, rd, roundf (val)); + return; + + case 6: /* mode X: use FPCR with exactness check. */ + case 7: /* mode I: use FPCR mode. */ + HALT_NYI; + + default: + HALT_UNALLOC; + } +} + +static void +dexSimpleFPDataProc1Source (sim_cpu *cpu) +{ + /* instr[31] ==> M : 0 ==> OK, 1 ==> UNALLOC + instr[30] = 0 + instr[29] ==> S : 0 ==> OK, 1 ==> UNALLOC + instr[28,25] = 1111 + instr[24] = 0 + instr[23,22] ==> type : 00 ==> source is single, + 01 ==> source is double + 10 ==> UNALLOC + 11 ==> UNALLOC or source is half + instr[21] = 1 + instr[20,15] ==> opcode : with type 00 or 01 + 000000 ==> FMOV, 000001 ==> FABS, + 000010 ==> FNEG, 000011 ==> FSQRT, + 000100 ==> UNALLOC, 000101 ==> FCVT,(to single/double) + 000110 ==> UNALLOC, 000111 ==> FCVT (to half) + 001000 ==> FRINTN, 001001 ==> FRINTP, + 001010 ==> FRINTM, 001011 ==> FRINTZ, + 001100 ==> FRINTA, 001101 ==> UNALLOC + 001110 ==> FRINTX, 001111 ==> FRINTI + with type 11 + 000100 ==> FCVT (half-to-single) + 000101 ==> FCVT (half-to-double) + instr[14,10] = 10000. */ + + uint32_t M_S = (uimm (aarch64_get_instr (cpu), 31, 31) << 1) + | uimm (aarch64_get_instr (cpu), 29, 29); + uint32_t type = uimm (aarch64_get_instr (cpu), 23, 22); + uint32_t opcode = uimm (aarch64_get_instr (cpu), 20, 15); + + if (M_S != 0) + HALT_UNALLOC; + + if (type == 3) + { + if (opcode == 4 || opcode == 5) + HALT_NYI; + else + HALT_UNALLOC; + } + + if (type == 2) + HALT_UNALLOC; + + switch (opcode) + { + case 0: + if (type) + ffmovd (cpu); + else + ffmovs (cpu); + return; + + case 1: + if (type) + fabcpu (cpu); + else + fabss (cpu); + return; + + case 2: + if (type) + fnegd (cpu); + else + fnegs (cpu); + return; + + case 3: + if (type) + fsqrtd (cpu); + else + fsqrts (cpu); + return; + + case 4: + if (type) + fcvtds (cpu); + else + HALT_UNALLOC; + return; + + case 5: + if (type) + HALT_UNALLOC; + fcvtcpu (cpu); + return; + + case 8: /* FRINTN etc. */ + case 9: + case 10: + case 11: + case 12: + case 14: + case 15: + do_FRINT (cpu); + return; + + case 7: /* FCVT double/single to half precision. */ + case 13: + HALT_NYI; + + default: + HALT_UNALLOC; + } +} + +/* 32 bit signed int to float. */ +static void +scvtf32 (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float + (cpu, sd, (float) aarch64_get_reg_s32 (cpu, rn, NO_SP)); +} + +/* signed int to float. */ +static void +scvtf (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_float + (cpu, sd, (float) aarch64_get_reg_s64 (cpu, rn, NO_SP)); +} + +/* 32 bit signed int to double. */ +static void +scvtd32 (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double + (cpu, sd, (double) aarch64_get_reg_s32 (cpu, rn, NO_SP)); +} + +/* signed int to double. */ +static void +scvtd (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned sd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_FP_double + (cpu, sd, (double) aarch64_get_reg_s64 (cpu, rn, NO_SP)); +} + +static const float FLOAT_INT_MAX = (float) INT_MAX; +static const float FLOAT_INT_MIN = (float) INT_MIN; +static const double DOUBLE_INT_MAX = (double) INT_MAX; +static const double DOUBLE_INT_MIN = (double) INT_MIN; +static const float FLOAT_LONG_MAX = (float) LONG_MAX; +static const float FLOAT_LONG_MIN = (float) LONG_MIN; +static const double DOUBLE_LONG_MAX = (double) LONG_MAX; +static const double DOUBLE_LONG_MIN = (double) LONG_MIN; + +/* Check for FP exception conditions: + NaN raises IO + Infinity raises IO + Out of Range raises IO and IX and saturates value + Denormal raises ID and IX and sets to zero. */ +#define RAISE_EXCEPTIONS(F, VALUE, FTYPE, ITYPE) \ + do \ + { \ + switch (fpclassify (F)) \ + { \ + case FP_INFINITE: \ + case FP_NAN: \ + aarch64_set_FPSR (cpu, IO); \ + if (signbit (F)) \ + VALUE = ITYPE##_MAX; \ + else \ + VALUE = ITYPE##_MIN; \ + break; \ + \ + case FP_NORMAL: \ + if (F >= FTYPE##_##ITYPE##_MAX) \ + { \ + aarch64_set_FPSR_bits (cpu, IO | IX, IO | IX); \ + VALUE = ITYPE##_MAX; \ + } \ + else if (F <= FTYPE##_##ITYPE##_MIN) \ + { \ + aarch64_set_FPSR_bits (cpu, IO | IX, IO | IX); \ + VALUE = ITYPE##_MIN; \ + } \ + break; \ + \ + case FP_SUBNORMAL: \ + aarch64_set_FPSR_bits (cpu, IO | IX | ID, IX | ID); \ + VALUE = 0; \ + break; \ + \ + default: \ + case FP_ZERO: \ + VALUE = 0; \ + break; \ + } \ + } \ + while (0) + +/* 32 bit convert float to signed int truncate towards zero. */ +static void +fcvtszs32 (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + /* TODO : check that this rounds toward zero. */ + float f = aarch64_get_FP_float (cpu, sn); + int32_t value = (int32_t) f; + + RAISE_EXCEPTIONS (f, value, FLOAT, INT); + + /* Avoid sign extension to 64 bit. */ + aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) value); +} + +/* 64 bit convert float to signed int truncate towards zero. */ +static void +fcvtszs (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + float f = aarch64_get_FP_float (cpu, sn); + int64_t value = (int64_t) f; + + RAISE_EXCEPTIONS (f, value, FLOAT, LONG); + + aarch64_set_reg_s64 (cpu, rd, NO_SP, value); +} + +/* 32 bit convert double to signed int truncate towards zero. */ +static void +fcvtszd32 (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + /* TODO : check that this rounds toward zero. */ + double d = aarch64_get_FP_double (cpu, sn); + int32_t value = (int32_t) d; + + RAISE_EXCEPTIONS (d, value, DOUBLE, INT); + + /* Avoid sign extension to 64 bit. */ + aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) value); +} + +/* 64 bit convert double to signed int truncate towards zero. */ +static void +fcvtszd (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + /* TODO : check that this rounds toward zero. */ + double d = aarch64_get_FP_double (cpu, sn); + int64_t value; + + value = (int64_t) d; + + RAISE_EXCEPTIONS (d, value, DOUBLE, LONG); + + aarch64_set_reg_s64 (cpu, rd, NO_SP, value); +} + +static void +do_fcvtzu (sim_cpu *cpu) +{ + /* instr[31] = size: 32-bit (0), 64-bit (1) + instr[30,23] = 00111100 + instr[22] = type: single (0)/ double (1) + instr[21] = enable (0)/disable(1) precision + instr[20,16] = 11001 + instr[15,10] = precision + instr[9,5] = Rs + instr[4,0] = Rd. */ + + unsigned rs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (30, 23, 0x3C); + NYI_assert (20, 16, 0x19); + + if (uimm (aarch64_get_instr (cpu), 21, 21) != 1) + /* Convert to fixed point. */ + HALT_NYI; + + if (uimm (aarch64_get_instr (cpu), 31, 31)) + { + /* Convert to unsigned 64-bit integer. */ + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + double d = aarch64_get_FP_double (cpu, rs); + uint64_t value = (uint64_t) d; + + /* Do not raise an exception if we have reached ULONG_MAX. */ + if (value != (1UL << 63)) + RAISE_EXCEPTIONS (d, value, DOUBLE, LONG); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value); + } + else + { + float f = aarch64_get_FP_float (cpu, rs); + uint64_t value = (uint64_t) f; + + /* Do not raise an exception if we have reached ULONG_MAX. */ + if (value != (1UL << 63)) + RAISE_EXCEPTIONS (f, value, FLOAT, LONG); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value); + } + } + else + { + uint32_t value; + + /* Convert to unsigned 32-bit integer. */ + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + double d = aarch64_get_FP_double (cpu, rs); + + value = (uint32_t) d; + /* Do not raise an exception if we have reached UINT_MAX. */ + if (value != (1UL << 31)) + RAISE_EXCEPTIONS (d, value, DOUBLE, INT); + } + else + { + float f = aarch64_get_FP_float (cpu, rs); + + value = (uint32_t) f; + /* Do not raise an exception if we have reached UINT_MAX. */ + if (value != (1UL << 31)) + RAISE_EXCEPTIONS (f, value, FLOAT, INT); + } + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value); + } +} + +static void +do_UCVTF (sim_cpu *cpu) +{ + /* instr[31] = size: 32-bit (0), 64-bit (1) + instr[30,23] = 001 1110 0 + instr[22] = type: single (0)/ double (1) + instr[21] = enable (0)/disable(1) precision + instr[20,16] = 0 0011 + instr[15,10] = precision + instr[9,5] = Rs + instr[4,0] = Rd. */ + + unsigned rs = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (30, 23, 0x3C); + NYI_assert (20, 16, 0x03); + + if (uimm (aarch64_get_instr (cpu), 21, 21) != 1) + HALT_NYI; + + /* FIXME: Add exception raising. */ + if (uimm (aarch64_get_instr (cpu), 31, 31)) + { + uint64_t value = aarch64_get_reg_u64 (cpu, rs, NO_SP); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + aarch64_set_FP_double (cpu, rd, (double) value); + else + aarch64_set_FP_float (cpu, rd, (float) value); + } + else + { + uint32_t value = aarch64_get_reg_u32 (cpu, rs, NO_SP); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + aarch64_set_FP_double (cpu, rd, (double) value); + else + aarch64_set_FP_float (cpu, rd, (float) value); + } +} + +static void +float_vector_move (sim_cpu *cpu) +{ + /* instr[31,17] == 100 1111 0101 0111 + instr[16] ==> direction 0=> to GR, 1=> from GR + instr[15,10] => ??? + instr[9,5] ==> source + instr[4,0] ==> dest. */ + + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (31, 17, 0x4F57); + + if (uimm (aarch64_get_instr (cpu), 15, 10) != 0) + HALT_UNALLOC; + + if (uimm (aarch64_get_instr (cpu), 16, 16)) + aarch64_set_vec_u64 (cpu, rd, 1, aarch64_get_reg_u64 (cpu, rn, NO_SP)); + else + aarch64_set_reg_u64 (cpu, rd, NO_SP, aarch64_get_vec_u64 (cpu, rn, 1)); +} + +static void +dexSimpleFPIntegerConvert (sim_cpu *cpu) +{ + /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[30 = 0 + instr[29] = S : 0 ==> OK, 1 ==> UNALLOC + instr[28,25] = 1111 + instr[24] = 0 + instr[23,22] = type : 00 ==> single, 01 ==> double, 1x ==> UNALLOC + instr[21] = 1 + instr[20,19] = rmode + instr[18,16] = opcode + instr[15,10] = 10 0000 */ + + uint32_t rmode_opcode; + uint32_t size_type; + uint32_t type; + uint32_t size; + uint32_t S; + + if (uimm (aarch64_get_instr (cpu), 31, 17) == 0x4F57) + { + float_vector_move (cpu); + return; + } + + size = uimm (aarch64_get_instr (cpu), 31, 31); + S = uimm (aarch64_get_instr (cpu), 29, 29); + if (S != 0) + HALT_UNALLOC; + + type = uimm (aarch64_get_instr (cpu), 23, 22); + if (type > 1) + HALT_UNALLOC; + + rmode_opcode = uimm (aarch64_get_instr (cpu), 20, 16); + size_type = (size << 1) | type; /* 0==32f, 1==32d, 2==64f, 3==64d. */ + + switch (rmode_opcode) + { + case 2: /* SCVTF. */ + switch (size_type) + { + case 0: scvtf32 (cpu); return; + case 1: scvtd32 (cpu); return; + case 2: scvtf (cpu); return; + case 3: scvtd (cpu); return; + default: + HALT_UNREACHABLE; + } + + case 6: /* FMOV GR, Vec. */ + switch (size_type) + { + case 0: gfmovs (cpu); return; + case 3: gfmovd (cpu); return; + default: HALT_UNALLOC; + } + + case 7: /* FMOV vec, GR. */ + switch (size_type) + { + case 0: fgmovs (cpu); return; + case 3: fgmovd (cpu); return; + default: HALT_UNALLOC; + } + + case 24: /* FCVTZS. */ + switch (size_type) + { + case 0: fcvtszs32 (cpu); return; + case 1: fcvtszd32 (cpu); return; + case 2: fcvtszs (cpu); return; + case 3: fcvtszd (cpu); return; + default: HALT_UNREACHABLE; + } + + case 25: do_fcvtzu (cpu); return; + case 3: do_UCVTF (cpu); return; + + case 0: /* FCVTNS. */ + case 1: /* FCVTNU. */ + case 4: /* FCVTAS. */ + case 5: /* FCVTAU. */ + case 8: /* FCVPTS. */ + case 9: /* FCVTPU. */ + case 16: /* FCVTMS. */ + case 17: /* FCVTMU. */ + default: + HALT_NYI; + } +} + +static void +set_flags_for_float_compare (sim_cpu *cpu, float fvalue1, float fvalue2) +{ + uint32_t flags; + + if (isnan (fvalue1) || isnan (fvalue2)) + flags = C|V; + else + { + float result = fvalue1 - fvalue2; + + if (result == 0.0) + flags = Z|C; + else if (result < 0) + flags = N; + else /* (result > 0). */ + flags = C; + } + + aarch64_set_CPSR (cpu, flags); +} + +static void +fcmps (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + + float fvalue1 = aarch64_get_FP_float (cpu, sn); + float fvalue2 = aarch64_get_FP_float (cpu, sm); + + set_flags_for_float_compare (cpu, fvalue1, fvalue2); +} + +/* Float compare to zero -- Invalid Operation exception + only on signaling NaNs. */ +static void +fcmpzs (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + float fvalue1 = aarch64_get_FP_float (cpu, sn); + + set_flags_for_float_compare (cpu, fvalue1, 0.0f); +} + +/* Float compare -- Invalid Operation exception on all NaNs. */ +static void +fcmpes (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + + float fvalue1 = aarch64_get_FP_float (cpu, sn); + float fvalue2 = aarch64_get_FP_float (cpu, sm); + + set_flags_for_float_compare (cpu, fvalue1, fvalue2); +} + +/* Float compare to zero -- Invalid Operation exception on all NaNs. */ +static void +fcmpzes (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + float fvalue1 = aarch64_get_FP_float (cpu, sn); + + set_flags_for_float_compare (cpu, fvalue1, 0.0f); +} + +static void +set_flags_for_double_compare (sim_cpu *cpu, double dval1, double dval2) +{ + uint32_t flags; + + if (isnan (dval1) || isnan (dval2)) + flags = C|V; + else + { + double result = dval1 - dval2; + + if (result == 0.0) + flags = Z|C; + else if (result < 0) + flags = N; + else /* (result > 0). */ + flags = C; + } + + aarch64_set_CPSR (cpu, flags); +} + +/* Double compare -- Invalid Operation exception only on signaling NaNs. */ +static void +fcmpd (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + + double dvalue1 = aarch64_get_FP_double (cpu, sn); + double dvalue2 = aarch64_get_FP_double (cpu, sm); + + set_flags_for_double_compare (cpu, dvalue1, dvalue2); +} + +/* Double compare to zero -- Invalid Operation exception + only on signaling NaNs. */ +static void +fcmpzd (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + double dvalue1 = aarch64_get_FP_double (cpu, sn); + + set_flags_for_double_compare (cpu, dvalue1, 0.0); +} + +/* Double compare -- Invalid Operation exception on all NaNs. */ +static void +fcmped (sim_cpu *cpu) +{ + unsigned sm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + + double dvalue1 = aarch64_get_FP_double (cpu, sn); + double dvalue2 = aarch64_get_FP_double (cpu, sm); + + set_flags_for_double_compare (cpu, dvalue1, dvalue2); +} + +/* Double compare to zero -- Invalid Operation exception on all NaNs. */ +static void +fcmpzed (sim_cpu *cpu) +{ + unsigned sn = uimm (aarch64_get_instr (cpu), 9, 5); + double dvalue1 = aarch64_get_FP_double (cpu, sn); + + set_flags_for_double_compare (cpu, dvalue1, 0.0); +} + +static void +dexSimpleFPCompare (sim_cpu *cpu) +{ + /* assert instr[28,25] == 1111 + instr[30:24:21:13,10] = 0011000 + instr[31] = M : 0 ==> OK, 1 ==> UNALLOC + instr[29] ==> S : 0 ==> OK, 1 ==> UNALLOC + instr[23,22] ==> type : 0 ==> single, 01 ==> double, 1x ==> UNALLOC + instr[15,14] ==> op : 00 ==> OK, ow ==> UNALLOC + instr[4,0] ==> opcode2 : 00000 ==> FCMP, 10000 ==> FCMPE, + 01000 ==> FCMPZ, 11000 ==> FCMPEZ, + ow ==> UNALLOC */ + uint32_t dispatch; + uint32_t M_S = (uimm (aarch64_get_instr (cpu), 31, 31) << 1) + | uimm (aarch64_get_instr (cpu), 29, 29); + uint32_t type = uimm (aarch64_get_instr (cpu), 23, 22); + uint32_t op = uimm (aarch64_get_instr (cpu), 15, 14); + uint32_t op2_2_0 = uimm (aarch64_get_instr (cpu), 2, 0); + + if (op2_2_0 != 0) + HALT_UNALLOC; + + if (M_S != 0) + HALT_UNALLOC; + + if (type > 1) + HALT_UNALLOC; + + if (op != 0) + HALT_UNALLOC; + + /* dispatch on type and top 2 bits of opcode. */ + dispatch = (type << 2) | uimm (aarch64_get_instr (cpu), 4, 3); + + switch (dispatch) + { + case 0: fcmps (cpu); return; + case 1: fcmpzs (cpu); return; + case 2: fcmpes (cpu); return; + case 3: fcmpzes (cpu); return; + case 4: fcmpd (cpu); return; + case 5: fcmpzd (cpu); return; + case 6: fcmped (cpu); return; + case 7: fcmpzed (cpu); return; + default: HALT_UNREACHABLE; + } +} + +static void +do_scalar_FADDP (sim_cpu *cpu) +{ + /* instr [31,23] = 011111100 + instr [22] = single(0)/double(1) + instr [21,10] = 1100 0011 0110 + instr [9,5] = Fn + instr [4,0] = Fd. */ + + unsigned Fn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned Fd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (31, 23, 0x0FC); + NYI_assert (21, 10, 0xC36); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + double val1 = aarch64_get_vec_double (cpu, Fn, 0); + double val2 = aarch64_get_vec_double (cpu, Fn, 1); + + aarch64_set_FP_double (cpu, Fd, val1 + val2); + } + else + { + float val1 = aarch64_get_vec_float (cpu, Fn, 0); + float val2 = aarch64_get_vec_float (cpu, Fn, 1); + + aarch64_set_FP_float (cpu, Fd, val1 + val2); + } +} + +/* Floating point absolute difference. */ + +static void +do_scalar_FABD (sim_cpu *cpu) +{ + /* instr [31,23] = 0111 1110 1 + instr [22] = float(0)/double(1) + instr [21] = 1 + instr [20,16] = Rm + instr [15,10] = 1101 01 + instr [9, 5] = Rn + instr [4, 0] = Rd. */ + + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (31, 23, 0x0FD); + NYI_assert (21, 21, 1); + NYI_assert (15, 10, 0x35); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + aarch64_set_FP_double (cpu, rd, + fabs (aarch64_get_FP_double (cpu, rn) + - aarch64_get_FP_double (cpu, rm))); + else + aarch64_set_FP_float (cpu, rd, + fabsf (aarch64_get_FP_float (cpu, rn) + - aarch64_get_FP_float (cpu, rm))); +} + +static void +do_scalar_CMGT (sim_cpu *cpu) +{ + /* instr [31,21] = 0101 1110 111 + instr [20,16] = Rm + instr [15,10] = 00 1101 + instr [9, 5] = Rn + instr [4, 0] = Rd. */ + + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (31, 21, 0x2F7); + NYI_assert (15, 10, 0x0D); + + aarch64_set_vec_u64 (cpu, rd, 0, + aarch64_get_vec_u64 (cpu, rn, 0) > + aarch64_get_vec_u64 (cpu, rm, 0) ? -1L : 0L); +} + +static void +do_scalar_USHR (sim_cpu *cpu) +{ + /* instr [31,23] = 0111 1111 0 + instr [22,16] = shift amount + instr [15,10] = 0000 01 + instr [9, 5] = Rn + instr [4, 0] = Rd. */ + + unsigned amount = 128 - uimm (aarch64_get_instr (cpu), 22, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (31, 23, 0x0FE); + NYI_assert (15, 10, 0x01); + + aarch64_set_vec_u64 (cpu, rd, 0, + aarch64_get_vec_u64 (cpu, rn, 0) >> amount); +} + +static void +do_scalar_SHL (sim_cpu *cpu) +{ + /* instr [31,23] = 0111 1101 0 + instr [22,16] = shift amount + instr [15,10] = 0101 01 + instr [9, 5] = Rn + instr [4, 0] = Rd. */ + + unsigned amount = uimm (aarch64_get_instr (cpu), 22, 16) - 64; + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (31, 23, 0x0BE); + NYI_assert (15, 10, 0x15); + + if (uimm (aarch64_get_instr (cpu), 22, 22) == 0) + HALT_UNALLOC; + + aarch64_set_vec_u64 (cpu, rd, 0, + aarch64_get_vec_u64 (cpu, rn, 0) << amount); +} + +/* FCMEQ FCMGT FCMGE. */ +static void +do_scalar_FCM (sim_cpu *cpu) +{ + /* instr [31,30] = 01 + instr [29] = U + instr [28,24] = 1 1110 + instr [23] = E + instr [22] = size + instr [21] = 1 + instr [20,16] = Rm + instr [15,12] = 1110 + instr [11] = AC + instr [10] = 1 + instr [9, 5] = Rn + instr [4, 0] = Rd. */ + + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned EUac = (uimm (aarch64_get_instr (cpu), 23, 23) << 2) + | (uimm (aarch64_get_instr (cpu), 29, 29) << 1) + | uimm (aarch64_get_instr (cpu), 11, 11); + unsigned result; + float val1; + float val2; + + NYI_assert (31, 30, 1); + NYI_assert (28, 24, 0x1E); + NYI_assert (21, 21, 1); + NYI_assert (15, 12, 0xE); + NYI_assert (10, 10, 1); + + if (uimm (aarch64_get_instr (cpu), 22, 22)) + { + double val1 = aarch64_get_FP_double (cpu, rn); + double val2 = aarch64_get_FP_double (cpu, rm); + + switch (EUac) + { + case 0: /* 000 */ + result = val1 == val2; + break; + + case 3: /* 011 */ + val1 = fabs (val1); + val2 = fabs (val2); + /* Fall through. */ + case 2: /* 010 */ + result = val1 >= val2; + break; + + case 7: /* 111 */ + val1 = fabs (val1); + val2 = fabs (val2); + /* Fall through. */ + case 6: /* 110 */ + result = val1 > val2; + break; + + default: + HALT_UNALLOC; + } + + aarch64_set_vec_u32 (cpu, rd, 0, result ? -1 : 0); + return; + } + + val1 = aarch64_get_FP_float (cpu, rn); + val2 = aarch64_get_FP_float (cpu, rm); + + switch (EUac) + { + case 0: /* 000 */ + result = val1 == val2; + break; + + case 3: /* 011 */ + val1 = fabsf (val1); + val2 = fabsf (val2); + /* Fall through. */ + case 2: /* 010 */ + result = val1 >= val2; + break; + + case 7: /* 111 */ + val1 = fabsf (val1); + val2 = fabsf (val2); + /* Fall through. */ + case 6: /* 110 */ + result = val1 > val2; + break; + + default: + HALT_UNALLOC; + } + + aarch64_set_vec_u32 (cpu, rd, 0, result ? -1 : 0); +} + +/* An alias of DUP. */ +static void +do_scalar_MOV (sim_cpu *cpu) +{ + /* instr [31,21] = 0101 1110 000 + instr [20,16] = imm5 + instr [15,10] = 0000 01 + instr [9, 5] = Rn + instr [4, 0] = Rd. */ + + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned index; + + NYI_assert (31, 21, 0x2F0); + NYI_assert (15, 10, 0x01); + + if (uimm (aarch64_get_instr (cpu), 16, 16)) + { + /* 8-bit. */ + index = uimm (aarch64_get_instr (cpu), 20, 17); + aarch64_set_vec_u8 + (cpu, rd, 0, aarch64_get_vec_u8 (cpu, rn, index)); + } + else if (uimm (aarch64_get_instr (cpu), 17, 17)) + { + /* 16-bit. */ + index = uimm (aarch64_get_instr (cpu), 20, 18); + aarch64_set_vec_u16 + (cpu, rd, 0, aarch64_get_vec_u16 (cpu, rn, index)); + } + else if (uimm (aarch64_get_instr (cpu), 18, 18)) + { + /* 32-bit. */ + index = uimm (aarch64_get_instr (cpu), 20, 19); + aarch64_set_vec_u32 + (cpu, rd, 0, aarch64_get_vec_u32 (cpu, rn, index)); + } + else if (uimm (aarch64_get_instr (cpu), 19, 19)) + { + /* 64-bit. */ + index = uimm (aarch64_get_instr (cpu), 20, 20); + aarch64_set_vec_u64 + (cpu, rd, 0, aarch64_get_vec_u64 (cpu, rn, index)); + } + else + HALT_UNALLOC; +} + +static void +do_double_add (sim_cpu *cpu) +{ + /* instr [28,25] = 1111. */ + unsigned Fd; + unsigned Fm; + unsigned Fn; + double val1; + double val2; + + switch (uimm (aarch64_get_instr (cpu), 31, 23)) + { + case 0xBC: + switch (uimm (aarch64_get_instr (cpu), 15, 10)) + { + case 0x01: do_scalar_MOV (cpu); return; + case 0x39: do_scalar_FCM (cpu); return; + case 0x3B: do_scalar_FCM (cpu); return; + } + break; + + case 0xBE: do_scalar_SHL (cpu); return; + + case 0xFC: + switch (uimm (aarch64_get_instr (cpu), 15, 10)) + { + case 0x36: do_scalar_FADDP (cpu); return; + case 0x39: do_scalar_FCM (cpu); return; + case 0x3B: do_scalar_FCM (cpu); return; + } + break; + + case 0xFD: + switch (uimm (aarch64_get_instr (cpu), 15, 10)) + { + case 0x0D: do_scalar_CMGT (cpu); return; + case 0x35: do_scalar_FABD (cpu); return; + case 0x39: do_scalar_FCM (cpu); return; + case 0x3B: do_scalar_FCM (cpu); return; + default: + HALT_NYI; + } + + case 0xFE: do_scalar_USHR (cpu); return; + default: + break; + } + + /* instr [31,21] = 0101 1110 111 + instr [20,16] = Fn + instr [15,10] = 1000 01 + instr [9,5] = Fm + instr [4,0] = Fd. */ + if (uimm (aarch64_get_instr (cpu), 31, 21) != 0x2F7 + || uimm (aarch64_get_instr (cpu), 15, 10) != 0x21) + HALT_NYI; + + Fd = uimm (aarch64_get_instr (cpu), 4, 0); + Fm = uimm (aarch64_get_instr (cpu), 9, 5); + Fn = uimm (aarch64_get_instr (cpu), 20, 16); + + val1 = aarch64_get_FP_double (cpu, Fm); + val2 = aarch64_get_FP_double (cpu, Fn); + + aarch64_set_FP_double (cpu, Fd, val1 + val2); +} + +static void +dexAdvSIMD1 (sim_cpu *cpu) +{ + /* instr [28,25] = 1 111. */ + + /* we are currently only interested in the basic + scalar fp routines which all have bit 30 = 0. */ + if (uimm (aarch64_get_instr (cpu), 30, 30)) + do_double_add (cpu); + + /* instr[24] is set for FP data processing 3-source and clear for + all other basic scalar fp instruction groups. */ + else if (uimm (aarch64_get_instr (cpu), 24, 24)) + dexSimpleFPDataProc3Source (cpu); + + /* instr[21] is clear for floating <-> fixed conversions and set for + all other basic scalar fp instruction groups. */ + else if (!uimm (aarch64_get_instr (cpu), 21, 21)) + dexSimpleFPFixedConvert (cpu); + + /* instr[11,10] : 01 ==> cond compare, 10 ==> Data Proc 2 Source + 11 ==> cond select, 00 ==> other. */ + else + switch (uimm (aarch64_get_instr (cpu), 11, 10)) + { + case 1: dexSimpleFPCondCompare (cpu); return; + case 2: dexSimpleFPDataProc2Source (cpu); return; + case 3: dexSimpleFPCondSelect (cpu); return; + + default: + /* Now an ordered cascade of tests. + FP immediate has aarch64_get_instr (cpu)[12] == 1. + FP compare has aarch64_get_instr (cpu)[13] == 1. + FP Data Proc 1 Source has aarch64_get_instr (cpu)[14] == 1. + FP floating <--> integer conversions has aarch64_get_instr (cpu)[15] == 0. */ + if (uimm (aarch64_get_instr (cpu), 12, 12)) + dexSimpleFPImmediate (cpu); + + else if (uimm (aarch64_get_instr (cpu), 13, 13)) + dexSimpleFPCompare (cpu); + + else if (uimm (aarch64_get_instr (cpu), 14, 14)) + dexSimpleFPDataProc1Source (cpu); + + else if (!uimm (aarch64_get_instr (cpu), 15, 15)) + dexSimpleFPIntegerConvert (cpu); + + else + /* If we get here then instr[15] == 1 which means UNALLOC. */ + HALT_UNALLOC; + } +} + +/* PC relative addressing. */ + +static void +pcadr (sim_cpu *cpu) +{ + /* instr[31] = op : 0 ==> ADR, 1 ==> ADRP + instr[30,29] = immlo + instr[23,5] = immhi. */ + uint64_t address; + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint32_t isPage = uimm (aarch64_get_instr (cpu), 31, 31); + union { int64_t u64; uint64_t s64; } imm; + uint64_t offset; + + imm.s64 = simm64 (aarch64_get_instr (cpu), 23, 5); + offset = imm.u64; + offset = (offset << 2) | uimm (aarch64_get_instr (cpu), 30, 29); + + address = aarch64_get_PC (cpu); + + if (isPage) + { + offset <<= 12; + address &= ~0xfff; + } + + aarch64_set_reg_u64 (cpu, rd, NO_SP, address + offset); +} + +/* Specific decode and execute for group Data Processing Immediate. */ + +static void +dexPCRelAddressing (sim_cpu *cpu) +{ + /* assert instr[28,24] = 10000. */ + pcadr (cpu); +} + +/* Immediate logical. + The bimm32/64 argument is constructed by replicating a 2, 4, 8, + 16, 32 or 64 bit sequence pulled out at decode and possibly + inverting it.. + + N.B. the output register (dest) can normally be Xn or SP + the exception occurs for flag setting instructions which may + only use Xn for the output (dest). The input register can + never be SP. */ + +/* 32 bit and immediate. */ +static void +and32 (sim_cpu *cpu, uint32_t bimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u32 (cpu, rn, NO_SP) & bimm); +} + +/* 64 bit and immediate. */ +static void +and64 (sim_cpu *cpu, uint64_t bimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u64 (cpu, rn, NO_SP) & bimm); +} + +/* 32 bit and immediate set flags. */ +static void +ands32 (sim_cpu *cpu, uint32_t bimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP); + uint32_t value2 = bimm; + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2); + set_flags_for_binop32 (cpu, value1 & value2); +} + +/* 64 bit and immediate set flags. */ +static void +ands64 (sim_cpu *cpu, uint64_t bimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP); + uint64_t value2 = bimm; + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2); + set_flags_for_binop64 (cpu, value1 & value2); +} + +/* 32 bit exclusive or immediate. */ +static void +eor32 (sim_cpu *cpu, uint32_t bimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u32 (cpu, rn, NO_SP) ^ bimm); +} + +/* 64 bit exclusive or immediate. */ +static void +eor64 (sim_cpu *cpu, uint64_t bimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u64 (cpu, rn, NO_SP) ^ bimm); +} + +/* 32 bit or immediate. */ +static void +orr32 (sim_cpu *cpu, uint32_t bimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u32 (cpu, rn, NO_SP) | bimm); +} + +/* 64 bit or immediate. */ +static void +orr64 (sim_cpu *cpu, uint64_t bimm) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, SP_OK, + aarch64_get_reg_u64 (cpu, rn, NO_SP) | bimm); +} + +/* Logical shifted register. + These allow an optional LSL, ASR, LSR or ROR to the second source + register with a count up to the register bit count. + N.B register args may not be SP. */ + +/* 32 bit AND shifted register. */ +static void +and32_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP) + & shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count)); +} + +/* 64 bit AND shifted register. */ +static void +and64_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP) + & shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count)); +} + +/* 32 bit AND shifted register setting flags. */ +static void +ands32_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP); + uint32_t value2 = shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), + shift, count); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2); + set_flags_for_binop32 (cpu, value1 & value2); +} + +/* 64 bit AND shifted register setting flags. */ +static void +ands64_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP); + uint64_t value2 = shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), + shift, count); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2); + set_flags_for_binop64 (cpu, value1 & value2); +} + +/* 32 bit BIC shifted register. */ +static void +bic32_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP) + & ~ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count)); +} + +/* 64 bit BIC shifted register. */ +static void +bic64_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP) + & ~ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count)); +} + +/* 32 bit BIC shifted register setting flags. */ +static void +bics32_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint32_t value1 = aarch64_get_reg_u32 (cpu, rn, NO_SP); + uint32_t value2 = ~ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), + shift, count); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2); + set_flags_for_binop32 (cpu, value1 & value2); +} + +/* 64 bit BIC shifted register setting flags. */ +static void +bics64_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP); + uint64_t value2 = ~ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), + shift, count); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, value1 & value2); + set_flags_for_binop64 (cpu, value1 & value2); +} + +/* 32 bit EON shifted register. */ +static void +eon32_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP) + ^ ~ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count)); +} + +/* 64 bit EON shifted register. */ +static void +eon64_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP) + ^ ~ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count)); +} + +/* 32 bit EOR shifted register. */ +static void +eor32_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP) + ^ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count)); +} + +/* 64 bit EOR shifted register. */ +static void +eor64_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP) + ^ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count)); +} + +/* 32 bit ORR shifted register. */ +static void +orr32_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP) + | shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count)); +} + +/* 64 bit ORR shifted register. */ +static void +orr64_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP) + | shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count)); +} + +/* 32 bit ORN shifted register. */ +static void +orn32_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, aarch64_get_reg_u32 (cpu, rn, NO_SP) + | ~ shifted32 (aarch64_get_reg_u32 (cpu, rm, NO_SP), shift, count)); +} + +/* 64 bit ORN shifted register. */ +static void +orn64_shift (sim_cpu *cpu, Shift shift, uint32_t count) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, aarch64_get_reg_u64 (cpu, rn, NO_SP) + | ~ shifted64 (aarch64_get_reg_u64 (cpu, rm, NO_SP), shift, count)); +} + +static void +dexLogicalImmediate (sim_cpu *cpu) +{ + /* assert instr[28,23] = 1001000 + instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[30,29] = op : 0 ==> AND, 1 ==> ORR, 2 ==> EOR, 3 ==> ANDS + instr[22] = N : used to construct immediate mask + instr[21,16] = immr + instr[15,10] = imms + instr[9,5] = Rn + instr[4,0] = Rd */ + + /* 32 bit operations must have N = 0 or else we have an UNALLOC. */ + uint32_t size = uimm (aarch64_get_instr (cpu), 31, 31); + uint32_t N = uimm (aarch64_get_instr (cpu), 22, 22); + /* uint32_t immr = uimm (aarch64_get_instr (cpu), 21, 16);. */ + /* uint32_t imms = uimm (aarch64_get_instr (cpu), 15, 10);. */ + uint32_t index = uimm (aarch64_get_instr (cpu), 22, 10); + uint64_t bimm64 = LITable [index]; + uint32_t dispatch = uimm (aarch64_get_instr (cpu), 30, 29); + + if (~size & N) + HALT_UNALLOC; + + if (!bimm64) + HALT_UNALLOC; + + if (size == 0) + { + uint32_t bimm = (uint32_t) bimm64; + + switch (dispatch) + { + case 0: and32 (cpu, bimm); return; + case 1: orr32 (cpu, bimm); return; + case 2: eor32 (cpu, bimm); return; + case 3: ands32 (cpu, bimm); return; + } + } + else + { + switch (dispatch) + { + case 0: and64 (cpu, bimm64); return; + case 1: orr64 (cpu, bimm64); return; + case 2: eor64 (cpu, bimm64); return; + case 3: ands64 (cpu, bimm64); return; + } + } + HALT_UNALLOC; +} + +/* Immediate move. + The uimm argument is a 16 bit value to be inserted into the + target register the pos argument locates the 16 bit word in the + dest register i.e. it is in {0, 1} for 32 bit and {0, 1, 2, + 3} for 64 bit. + N.B register arg may not be SP so it should be. + accessed using the setGZRegisterXXX accessors. */ + +/* 32 bit move 16 bit immediate zero remaining shorts. */ +static void +movz32 (sim_cpu *cpu, uint32_t val, uint32_t pos) +{ + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, val << (pos * 16)); +} + +/* 64 bit move 16 bit immediate zero remaining shorts. */ +static void +movz64 (sim_cpu *cpu, uint32_t val, uint32_t pos) +{ + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, ((uint64_t) val) << (pos * 16)); +} + +/* 32 bit move 16 bit immediate negated. */ +static void +movn32 (sim_cpu *cpu, uint32_t val, uint32_t pos) +{ + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, ((val << (pos * 16)) ^ 0xffffffffU)); +} + +/* 64 bit move 16 bit immediate negated. */ +static void +movn64 (sim_cpu *cpu, uint32_t val, uint32_t pos) +{ + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, ((((uint64_t) val) << (pos * 16)) + ^ 0xffffffffffffffffULL)); +} + +/* 32 bit move 16 bit immediate keep remaining shorts. */ +static void +movk32 (sim_cpu *cpu, uint32_t val, uint32_t pos) +{ + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint32_t current = aarch64_get_reg_u32 (cpu, rd, NO_SP); + uint32_t value = val << (pos * 16); + uint32_t mask = ~(0xffffU << (pos * 16)); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, (value | (current & mask))); +} + +/* 64 bit move 16 it immediate keep remaining shorts. */ +static void +movk64 (sim_cpu *cpu, uint32_t val, uint32_t pos) +{ + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t current = aarch64_get_reg_u64 (cpu, rd, NO_SP); + uint64_t value = (uint64_t) val << (pos * 16); + uint64_t mask = ~(0xffffULL << (pos * 16)); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, (value | (current & mask))); +} + +static void +dexMoveWideImmediate (sim_cpu *cpu) +{ + /* assert instr[28:23] = 100101 + instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[30,29] = op : 0 ==> MOVN, 1 ==> UNALLOC, 2 ==> MOVZ, 3 ==> MOVK + instr[22,21] = shift : 00 == LSL#0, 01 = LSL#16, 10 = LSL#32, 11 = LSL#48 + instr[20,5] = uimm16 + instr[4,0] = Rd */ + + /* N.B. the (multiple of 16) shift is applied by the called routine, + we just pass the multiplier. */ + + uint32_t imm; + uint32_t size = uimm (aarch64_get_instr (cpu), 31, 31); + uint32_t op = uimm (aarch64_get_instr (cpu), 30, 29); + uint32_t shift = uimm (aarch64_get_instr (cpu), 22, 21); + + /* 32 bit can only shift 0 or 1 lot of 16. + anything else is an unallocated instruction. */ + if (size == 0 && (shift > 1)) + HALT_UNALLOC; + + if (op == 1) + HALT_UNALLOC; + + imm = uimm (aarch64_get_instr (cpu), 20, 5); + + if (size == 0) + { + if (op == 0) + movn32 (cpu, imm, shift); + else if (op == 2) + movz32 (cpu, imm, shift); + else + movk32 (cpu, imm, shift); + } + else + { + if (op == 0) + movn64 (cpu, imm, shift); + else if (op == 2) + movz64 (cpu, imm, shift); + else + movk64 (cpu, imm, shift); + } +} + +/* Bitfield operations. + These take a pair of bit positions r and s which are in {0..31} + or {0..63} depending on the instruction word size. + N.B register args may not be SP. */ + +/* OK, we start with ubfm which just needs to pick + some bits out of source zero the rest and write + the result to dest. Just need two logical shifts. */ + +/* 32 bit bitfield move, left and right of affected zeroed + if r <= s Wd<s-r:0> = Wn<s:r> else Wd<32+s-r,32-r> = Wn<s:0>. */ +static void +ubfm32 (sim_cpu *cpu, uint32_t r, uint32_t s) +{ + unsigned rd; + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP); + + /* Pick either s+1-r or s+1 consecutive bits out of the original word. */ + if (r <= s) + { + /* 31:...:s:xxx:r:...:0 ==> 31:...:s-r:xxx:0. + We want only bits s:xxx:r at the bottom of the word + so we LSL bit s up to bit 31 i.e. by 31 - s + and then we LSR to bring bit 31 down to bit s - r + i.e. by 31 + r - s. */ + value <<= 31 - s; + value >>= 31 + r - s; + } + else + { + /* 31:...:s:xxx:0 ==> 31:...:31-(r-1)+s:xxx:31-(r-1):...:0 + We want only bits s:xxx:0 starting at it 31-(r-1) + so we LSL bit s up to bit 31 i.e. by 31 - s + and then we LSL to bring bit 31 down to 31-(r-1)+s + i.e. by r - (s + 1). */ + value <<= 31 - s; + value >>= r - (s + 1); + } + + rd = uimm (aarch64_get_instr (cpu), 4, 0); + aarch64_set_reg_u64 (cpu, rd, NO_SP, value); +} + +/* 64 bit bitfield move, left and right of affected zeroed + if r <= s Wd<s-r:0> = Wn<s:r> else Wd<64+s-r,64-r> = Wn<s:0>. */ +static void +ubfm (sim_cpu *cpu, uint32_t r, uint32_t s) +{ + unsigned rd; + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP); + + if (r <= s) + { + /* 63:...:s:xxx:r:...:0 ==> 63:...:s-r:xxx:0. + We want only bits s:xxx:r at the bottom of the word. + So we LSL bit s up to bit 63 i.e. by 63 - s + and then we LSR to bring bit 63 down to bit s - r + i.e. by 63 + r - s. */ + value <<= 63 - s; + value >>= 63 + r - s; + } + else + { + /* 63:...:s:xxx:0 ==> 63:...:63-(r-1)+s:xxx:63-(r-1):...:0. + We want only bits s:xxx:0 starting at it 63-(r-1). + So we LSL bit s up to bit 63 i.e. by 63 - s + and then we LSL to bring bit 63 down to 63-(r-1)+s + i.e. by r - (s + 1). */ + value <<= 63 - s; + value >>= r - (s + 1); + } + + rd = uimm (aarch64_get_instr (cpu), 4, 0); + aarch64_set_reg_u64 (cpu, rd, NO_SP, value); +} + +/* The signed versions need to insert sign bits + on the left of the inserted bit field. so we do + much the same as the unsigned version except we + use an arithmetic shift right -- this just means + we need to operate on signed values. */ + +/* 32 bit bitfield move, left of affected sign-extended, right zeroed. */ +/* If r <= s Wd<s-r:0> = Wn<s:r> else Wd<32+s-r,32-r> = Wn<s:0>. */ +static void +sbfm32 (sim_cpu *cpu, uint32_t r, uint32_t s) +{ + unsigned rd; + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + /* as per ubfm32 but use an ASR instead of an LSR. */ + int32_t value = aarch64_get_reg_s32 (cpu, rn, NO_SP); + + if (r <= s) + { + value <<= 31 - s; + value >>= 31 + r - s; + } + else + { + value <<= 31 - s; + value >>= r - (s + 1); + } + + rd = uimm (aarch64_get_instr (cpu), 4, 0); + aarch64_set_reg_u64 (cpu, rd, NO_SP, (uint32_t) value); +} + +/* 64 bit bitfield move, left of affected sign-extended, right zeroed. */ +/* If r <= s Wd<s-r:0> = Wn<s:r> else Wd<64+s-r,64-r> = Wn<s:0>. */ +static void +sbfm (sim_cpu *cpu, uint32_t r, uint32_t s) +{ + unsigned rd; + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + /* acpu per ubfm but use an ASR instead of an LSR. */ + int64_t value = aarch64_get_reg_s64 (cpu, rn, NO_SP); + + if (r <= s) + { + value <<= 63 - s; + value >>= 63 + r - s; + } + else + { + value <<= 63 - s; + value >>= r - (s + 1); + } + + rd = uimm (aarch64_get_instr (cpu), 4, 0); + aarch64_set_reg_s64 (cpu, rd, NO_SP, value); +} + +/* Finally, these versions leave non-affected bits + as is. so we need to generate the bits as per + ubfm and also generate a mask to pick the + bits from the original and computed values. */ + +/* 32 bit bitfield move, non-affected bits left as is. + If r <= s Wd<s-r:0> = Wn<s:r> else Wd<32+s-r,32-r> = Wn<s:0>. */ +static void +bfm32 (sim_cpu *cpu, uint32_t r, uint32_t s) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP); + uint32_t mask = -1; + unsigned rd; + uint32_t value2; + + /* Pick either s+1-r or s+1 consecutive bits out of the original word. */ + if (r <= s) + { + /* 31:...:s:xxx:r:...:0 ==> 31:...:s-r:xxx:0. + We want only bits s:xxx:r at the bottom of the word + so we LSL bit s up to bit 31 i.e. by 31 - s + and then we LSR to bring bit 31 down to bit s - r + i.e. by 31 + r - s. */ + value <<= 31 - s; + value >>= 31 + r - s; + /* the mask must include the same bits. */ + mask <<= 31 - s; + mask >>= 31 + r - s; + } + else + { + /* 31:...:s:xxx:0 ==> 31:...:31-(r-1)+s:xxx:31-(r-1):...:0. + We want only bits s:xxx:0 starting at it 31-(r-1) + so we LSL bit s up to bit 31 i.e. by 31 - s + and then we LSL to bring bit 31 down to 31-(r-1)+s + i.e. by r - (s + 1). */ + value <<= 31 - s; + value >>= r - (s + 1); + /* The mask must include the same bits. */ + mask <<= 31 - s; + mask >>= r - (s + 1); + } + + rd = uimm (aarch64_get_instr (cpu), 4, 0); + value2 = aarch64_get_reg_u32 (cpu, rd, NO_SP); + + value2 &= ~mask; + value2 |= value; + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, (aarch64_get_reg_u32 (cpu, rd, NO_SP) & ~mask) | value); +} + +/* 64 bit bitfield move, non-affected bits left as is. + If r <= s Wd<s-r:0> = Wn<s:r> else Wd<64+s-r,64-r> = Wn<s:0>. */ +static void +bfm (sim_cpu *cpu, uint32_t r, uint32_t s) +{ + unsigned rd; + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP); + uint64_t mask = 0xffffffffffffffffULL; + + if (r <= s) + { + /* 63:...:s:xxx:r:...:0 ==> 63:...:s-r:xxx:0. + We want only bits s:xxx:r at the bottom of the word + so we LSL bit s up to bit 63 i.e. by 63 - s + and then we LSR to bring bit 63 down to bit s - r + i.e. by 63 + r - s. */ + value <<= 63 - s; + value >>= 63 + r - s; + /* The mask must include the same bits. */ + mask <<= 63 - s; + mask >>= 63 + r - s; + } + else + { + /* 63:...:s:xxx:0 ==> 63:...:63-(r-1)+s:xxx:63-(r-1):...:0 + We want only bits s:xxx:0 starting at it 63-(r-1) + so we LSL bit s up to bit 63 i.e. by 63 - s + and then we LSL to bring bit 63 down to 63-(r-1)+s + i.e. by r - (s + 1). */ + value <<= 63 - s; + value >>= r - (s + 1); + /* The mask must include the same bits. */ + mask <<= 63 - s; + mask >>= r - (s + 1); + } + + rd = uimm (aarch64_get_instr (cpu), 4, 0); + aarch64_set_reg_u64 + (cpu, rd, NO_SP, (aarch64_get_reg_u64 (cpu, rd, NO_SP) & ~mask) | value); +} + +static void +dexBitfieldImmediate (sim_cpu *cpu) +{ + /* assert instr[28:23] = 100110 + instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[30,29] = op : 0 ==> SBFM, 1 ==> BFM, 2 ==> UBFM, 3 ==> UNALLOC + instr[22] = N : must be 0 for 32 bit, 1 for 64 bit ow UNALLOC + instr[21,16] = immr : 0xxxxx for 32 bit, xxxxxx for 64 bit + instr[15,10] = imms : 0xxxxx for 32 bit, xxxxxx for 64 bit + instr[9,5] = Rn + instr[4,0] = Rd */ + + /* 32 bit operations must have N = 0 or else we have an UNALLOC. */ + uint32_t dispatch; + uint32_t imms; + uint32_t size = uimm (aarch64_get_instr (cpu), 31, 31); + uint32_t N = uimm (aarch64_get_instr (cpu), 22, 22); + /* 32 bit operations must have immr[5] = 0 and imms[5] = 0. */ + /* or else we have an UNALLOC. */ + uint32_t immr = uimm (aarch64_get_instr (cpu), 21, 16); + + if (~size & N) + HALT_UNALLOC; + + if (!size && uimm (immr, 5, 5)) + HALT_UNALLOC; + + imms = uimm (aarch64_get_instr (cpu), 15, 10); + if (!size && uimm (imms, 5, 5)) + HALT_UNALLOC; + + /* Switch on combined size and op. */ + dispatch = uimm (aarch64_get_instr (cpu), 31, 29); + switch (dispatch) + { + case 0: sbfm32 (cpu, immr, imms); return; + case 1: bfm32 (cpu, immr, imms); return; + case 2: ubfm32 (cpu, immr, imms); return; + case 4: sbfm (cpu, immr, imms); return; + case 5: bfm (cpu, immr, imms); return; + case 6: ubfm (cpu, immr, imms); return; + default: HALT_UNALLOC; + } +} + +static void +do_EXTR_32 (sim_cpu *cpu) +{ + /* instr[31:21] = 00010011100 + instr[20,16] = Rm + instr[15,10] = imms : 0xxxxx for 32 bit + instr[9,5] = Rn + instr[4,0] = Rd */ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned imms = uimm (aarch64_get_instr (cpu), 15, 10) & 31; + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t val1; + uint64_t val2; + + val1 = aarch64_get_reg_u32 (cpu, rm, NO_SP); + val1 >>= imms; + val2 = aarch64_get_reg_u32 (cpu, rn, NO_SP); + val2 <<= (32 - imms); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, val1 | val2); +} + +static void +do_EXTR_64 (sim_cpu *cpu) +{ + /* instr[31:21] = 10010011100 + instr[20,16] = Rm + instr[15,10] = imms + instr[9,5] = Rn + instr[4,0] = Rd */ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned imms = uimm (aarch64_get_instr (cpu), 15, 10) & 63; + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t val; + + val = aarch64_get_reg_u64 (cpu, rm, NO_SP); + val >>= imms; + val |= (aarch64_get_reg_u64 (cpu, rn, NO_SP) << (64 - imms)); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, val); +} + +static void +dexExtractImmediate (sim_cpu *cpu) +{ + /* assert instr[28:23] = 100111 + instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[30,29] = op21 : 0 ==> EXTR, 1,2,3 ==> UNALLOC + instr[22] = N : must be 0 for 32 bit, 1 for 64 bit or UNALLOC + instr[21] = op0 : must be 0 or UNALLOC + instr[20,16] = Rm + instr[15,10] = imms : 0xxxxx for 32 bit, xxxxxx for 64 bit + instr[9,5] = Rn + instr[4,0] = Rd */ + + /* 32 bit operations must have N = 0 or else we have an UNALLOC. */ + /* 64 bit operations must have N = 1 or else we have an UNALLOC. */ + uint32_t dispatch; + uint32_t size = uimm (aarch64_get_instr (cpu), 31, 31); + uint32_t N = uimm (aarch64_get_instr (cpu), 22, 22); + /* 32 bit operations must have imms[5] = 0 + or else we have an UNALLOC. */ + uint32_t imms = uimm (aarch64_get_instr (cpu), 15, 10); + + if (size ^ N) + HALT_UNALLOC; + + if (!size && uimm (imms, 5, 5)) + HALT_UNALLOC; + + /* Switch on combined size and op. */ + dispatch = uimm (aarch64_get_instr (cpu), 31, 29); + + if (dispatch == 0) + do_EXTR_32 (cpu); + + else if (dispatch == 4) + do_EXTR_64 (cpu); + + else if (dispatch == 1) + HALT_NYI; + else + HALT_UNALLOC; +} + +static void +dexDPImm (sim_cpu *cpu) +{ + /* uint32_t group = dispatchGroup (aarch64_get_instr (cpu)); + assert group == GROUP_DPIMM_1000 || grpoup == GROUP_DPIMM_1001 + bits [25,23] of a DPImm are the secondary dispatch vector. */ + uint32_t group2 = dispatchDPImm (aarch64_get_instr (cpu)); + + switch (group2) + { + case DPIMM_PCADR_000: + case DPIMM_PCADR_001: + dexPCRelAddressing (cpu); + return; + + case DPIMM_ADDSUB_010: + case DPIMM_ADDSUB_011: + dexAddSubtractImmediate (cpu); + return; + + case DPIMM_LOG_100: + dexLogicalImmediate (cpu); + return; + + case DPIMM_MOV_101: + dexMoveWideImmediate (cpu); + return; + + case DPIMM_BITF_110: + dexBitfieldImmediate (cpu); + return; + + case DPIMM_EXTR_111: + dexExtractImmediate (cpu); + return; + + default: + /* Should never reach here. */ + HALT_NYI; + } +} + +static void +dexLoadUnscaledImmediate (sim_cpu *cpu) +{ + /* instr[29,24] == 111_00 + instr[21] == 0 + instr[11,10] == 00 + instr[31,30] = size + instr[26] = V + instr[23,22] = opc + instr[20,12] = simm9 + instr[9,5] = rn may be SP. */ + /* unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); */ + uint32_t V = uimm (aarch64_get_instr (cpu), 26, 26); + uint32_t dispatch = ( (uimm (aarch64_get_instr (cpu), 31, 30) << 2) + | uimm (aarch64_get_instr (cpu), 23, 22)); + int32_t imm = simm32 (aarch64_get_instr (cpu), 20, 12); + + if (!V) + { + /* GReg operations. */ + switch (dispatch) + { + case 0: sturb (cpu, imm); return; + case 1: ldurb32 (cpu, imm); return; + case 2: ldursb64 (cpu, imm); return; + case 3: ldursb32 (cpu, imm); return; + case 4: sturh (cpu, imm); return; + case 5: ldurh32 (cpu, imm); return; + case 6: ldursh64 (cpu, imm); return; + case 7: ldursh32 (cpu, imm); return; + case 8: stur32 (cpu, imm); return; + case 9: ldur32 (cpu, imm); return; + case 10: ldursw (cpu, imm); return; + case 12: stur64 (cpu, imm); return; + case 13: ldur64 (cpu, imm); return; + + case 14: + /* PRFUM NYI. */ + HALT_NYI; + + default: + case 11: + case 15: + HALT_UNALLOC; + } + } + + /* FReg operations. */ + switch (dispatch) + { + case 2: fsturq (cpu, imm); return; + case 3: fldurq (cpu, imm); return; + case 8: fsturs (cpu, imm); return; + case 9: fldurs (cpu, imm); return; + case 12: fsturd (cpu, imm); return; + case 13: fldurd (cpu, imm); return; + + case 0: /* STUR 8 bit FP. */ + case 1: /* LDUR 8 bit FP. */ + case 4: /* STUR 16 bit FP. */ + case 5: /* LDUR 8 bit FP. */ + HALT_NYI; + + default: + case 6: + case 7: + case 10: + case 11: + case 14: + case 15: + HALT_UNALLOC; + } +} + +/* N.B. A preliminary note regarding all the ldrs<x>32 + instructions + + The signed value loaded by these instructions is cast to unsigned + before being assigned to aarch64_get_reg_u64 (cpu, N) i.e. to the + 64 bit element of the GReg union. this performs a 32 bit sign extension + (as required) but avoids 64 bit sign extension, thus ensuring that the + top half of the register word is zero. this is what the spec demands + when a 32 bit load occurs. */ + +/* 32 bit load sign-extended byte scaled unsigned 12 bit. */ +static void +ldrsb32_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int rt = uimm (aarch64_get_instr (cpu), 4, 0); + + /* The target register may not be SP but the source may be + there is no scaling required for a byte load. */ + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset; + aarch64_set_reg_u64 (cpu, rt, NO_SP, + (int64_t) aarch64_get_mem_s8 (cpu, address)); +} + +/* 32 bit load sign-extended byte scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +ldrsb32_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned int rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int rt = uimm (aarch64_get_instr (cpu), 4, 0); + + /* rn may reference SP, rm and rt must reference ZR. */ + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t displacement = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), + extension); + + /* There is no scaling required for a byte load. */ + aarch64_set_reg_u64 + (cpu, rt, NO_SP, (int64_t) aarch64_get_mem_s8 (cpu, address + + displacement)); +} + +/* 32 bit load sign-extended byte unscaled signed 9 bit with + pre- or post-writeback. */ +static void +ldrsb32_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + uint64_t address; + unsigned int rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned int rt = uimm (aarch64_get_instr (cpu), 4, 0); + + if (rn == rt && wb != NoWriteBack) + HALT_UNALLOC; + + address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb == Pre) + address += offset; + + aarch64_set_reg_u64 (cpu, rt, NO_SP, + (int64_t) aarch64_get_mem_s8 (cpu, address)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, NO_SP, address); +} + +/* 8 bit store scaled. */ +static void +fstrb_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + + aarch64_set_mem_u8 (cpu, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + offset, + aarch64_get_vec_u8 (cpu, st, 0)); +} + +/* 8 bit store scaled or unscaled zero- or + sign-extended 8-bit register offset. */ +static void +fstrb_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), + extension); + uint64_t displacement = OPT_SCALE (extended, 32, scaling); + + aarch64_set_mem_u8 + (cpu, address + displacement, aarch64_get_vec_u8 (cpu, st, 0)); +} + +/* 16 bit store scaled. */ +static void +fstrh_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + + aarch64_set_mem_u16 + (cpu, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 16), + aarch64_get_vec_u16 (cpu, st, 0)); +} + +/* 16 bit store scaled or unscaled zero- + or sign-extended 16-bit register offset. */ +static void +fstrh_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), + extension); + uint64_t displacement = OPT_SCALE (extended, 32, scaling); + + aarch64_set_mem_u16 + (cpu, address + displacement, aarch64_get_vec_u16 (cpu, st, 0)); +} + +/* 32 bit store scaled unsigned 12 bit. */ +static void +fstrs_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + + aarch64_set_mem_float + (cpu, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 32), + aarch64_get_FP_float (cpu, st)); +} + +/* 32 bit store unscaled signed 9 bit with pre- or post-writeback. */ +static void +fstrs_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_mem_float (cpu, address, aarch64_get_FP_float (cpu, st)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 32 bit store scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +fstrs_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), + extension); + uint64_t displacement = OPT_SCALE (extended, 32, scaling); + + aarch64_set_mem_float + (cpu, address + displacement, aarch64_get_FP_float (cpu, st)); +} + +/* 64 bit store scaled unsigned 12 bit. */ +static void +fstrd_abs (sim_cpu *cpu, uint32_t offset) +{ + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + + aarch64_set_mem_double + (cpu, + aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 64), + aarch64_get_FP_double (cpu, st)); +} + +/* 64 bit store unscaled signed 9 bit with pre- or post-writeback. */ +static void +fstrd_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_set_mem_double (cpu, address, aarch64_get_FP_double (cpu, st)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 64 bit store scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +fstrd_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), + extension); + uint64_t displacement = OPT_SCALE (extended, 64, scaling); + + aarch64_set_mem_double + (cpu, address + displacement, aarch64_get_FP_double (cpu, st)); +} + +/* 128 bit store scaled unsigned 12 bit. */ +static void +fstrq_abs (sim_cpu *cpu, uint32_t offset) +{ + FRegister a; + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + uint64_t addr; + + aarch64_get_FP_long_double (cpu, st, & a); + + addr = aarch64_get_reg_u64 (cpu, rn, SP_OK) + SCALE (offset, 128); + aarch64_set_mem_long_double (cpu, addr, a); +} + +/* 128 bit store unscaled signed 9 bit with pre- or post-writeback. */ +static void +fstrq_wb (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + FRegister a; + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + + if (wb != Post) + address += offset; + + aarch64_get_FP_long_double (cpu, st, & a); + aarch64_set_mem_long_double (cpu, address, a); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rn, SP_OK, address); +} + +/* 128 bit store scaled or unscaled zero- + or sign-extended 32-bit register offset. */ +static void +fstrq_scale_ext (sim_cpu *cpu, Scaling scaling, Extension extension) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned st = uimm (aarch64_get_instr (cpu), 4, 0); + + uint64_t address = aarch64_get_reg_u64 (cpu, rn, SP_OK); + int64_t extended = extend (aarch64_get_reg_u32 (cpu, rm, NO_SP), + extension); + uint64_t displacement = OPT_SCALE (extended, 128, scaling); + + FRegister a; + + aarch64_get_FP_long_double (cpu, st, & a); + aarch64_set_mem_long_double (cpu, address + displacement, a); +} + +static void +dexLoadImmediatePrePost (sim_cpu *cpu) +{ + /* instr[29,24] == 111_00 + instr[21] == 0 + instr[11,10] == 00 + instr[31,30] = size + instr[26] = V + instr[23,22] = opc + instr[20,12] = simm9 + instr[11] = wb : 0 ==> Post, 1 ==> Pre + instr[9,5] = rn may be SP. */ + /* unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); */ + uint32_t V = uimm (aarch64_get_instr (cpu), 26, 26); + uint32_t dispatch = ( (uimm (aarch64_get_instr (cpu), 31, 30) << 2) + | uimm (aarch64_get_instr (cpu), 23, 22)); + int32_t imm = simm32 (aarch64_get_instr (cpu), 20, 12); + WriteBack wb = writeback (aarch64_get_instr (cpu), 11); + + if (!V) + { + /* GReg operations. */ + switch (dispatch) + { + case 0: strb_wb (cpu, imm, wb); return; + case 1: ldrb32_wb (cpu, imm, wb); return; + case 2: ldrsb_wb (cpu, imm, wb); return; + case 3: ldrsb32_wb (cpu, imm, wb); return; + case 4: strh_wb (cpu, imm, wb); return; + case 5: ldrh32_wb (cpu, imm, wb); return; + case 6: ldrsh64_wb (cpu, imm, wb); return; + case 7: ldrsh32_wb (cpu, imm, wb); return; + case 8: str32_wb (cpu, imm, wb); return; + case 9: ldr32_wb (cpu, imm, wb); return; + case 10: ldrsw_wb (cpu, imm, wb); return; + case 12: str_wb (cpu, imm, wb); return; + case 13: ldr_wb (cpu, imm, wb); return; + + default: + case 11: + case 14: + case 15: + HALT_UNALLOC; + } + } + + /* FReg operations. */ + switch (dispatch) + { + case 2: fstrq_wb (cpu, imm, wb); return; + case 3: fldrq_wb (cpu, imm, wb); return; + case 8: fstrs_wb (cpu, imm, wb); return; + case 9: fldrs_wb (cpu, imm, wb); return; + case 12: fstrd_wb (cpu, imm, wb); return; + case 13: fldrd_wb (cpu, imm, wb); return; + + case 0: /* STUR 8 bit FP. */ + case 1: /* LDUR 8 bit FP. */ + case 4: /* STUR 16 bit FP. */ + case 5: /* LDUR 8 bit FP. */ + HALT_NYI; + + default: + case 6: + case 7: + case 10: + case 11: + case 14: + case 15: + HALT_UNALLOC; + } +} + +static void +dexLoadRegisterOffset (sim_cpu *cpu) +{ + /* instr[31,30] = size + instr[29,27] = 111 + instr[26] = V + instr[25,24] = 00 + instr[23,22] = opc + instr[21] = 1 + instr[20,16] = rm + instr[15,13] = option : 010 ==> UXTW, 011 ==> UXTX/LSL, + 110 ==> SXTW, 111 ==> SXTX, + ow ==> RESERVED + instr[12] = scaled + instr[11,10] = 10 + instr[9,5] = rn + instr[4,0] = rt. */ + + uint32_t V = uimm (aarch64_get_instr (cpu), 26,26); + uint32_t dispatch = ( (uimm (aarch64_get_instr (cpu), 31, 30) << 2) + | uimm (aarch64_get_instr (cpu), 23, 22)); + Scaling scale = scaling (aarch64_get_instr (cpu), 12); + Extension extensionType = extension (aarch64_get_instr (cpu), 13); + + /* Check for illegal extension types. */ + if (uimm (extensionType, 1, 1) == 0) + HALT_UNALLOC; + + if (extensionType == UXTX || extensionType == SXTX) + extensionType = NoExtension; + + if (!V) + { + /* GReg operations. */ + switch (dispatch) + { + case 0: strb_scale_ext (cpu, scale, extensionType); return; + case 1: ldrb32_scale_ext (cpu, scale, extensionType); return; + case 2: ldrsb_scale_ext (cpu, scale, extensionType); return; + case 3: ldrsb32_scale_ext (cpu, scale, extensionType); return; + case 4: strh_scale_ext (cpu, scale, extensionType); return; + case 5: ldrh32_scale_ext (cpu, scale, extensionType); return; + case 6: ldrsh_scale_ext (cpu, scale, extensionType); return; + case 7: ldrsh32_scale_ext (cpu, scale, extensionType); return; + case 8: str32_scale_ext (cpu, scale, extensionType); return; + case 9: ldr32_scale_ext (cpu, scale, extensionType); return; + case 10: ldrsw_scale_ext (cpu, scale, extensionType); return; + case 12: str_scale_ext (cpu, scale, extensionType); return; + case 13: ldr_scale_ext (cpu, scale, extensionType); return; + case 14: prfm_scale_ext (cpu, scale, extensionType); return; + + default: + case 11: + case 15: + HALT_UNALLOC; + } + } + + /* FReg operations. */ + switch (dispatch) + { + case 1: /* LDUR 8 bit FP. */ + HALT_NYI; + case 3: fldrq_scale_ext (cpu, scale, extensionType); return; + case 5: /* LDUR 8 bit FP. */ + HALT_NYI; + case 9: fldrs_scale_ext (cpu, scale, extensionType); return; + case 13: fldrd_scale_ext (cpu, scale, extensionType); return; + + case 0: fstrb_scale_ext (cpu, scale, extensionType); return; + case 2: fstrq_scale_ext (cpu, scale, extensionType); return; + case 4: fstrh_scale_ext (cpu, scale, extensionType); return; + case 8: fstrs_scale_ext (cpu, scale, extensionType); return; + case 12: fstrd_scale_ext (cpu, scale, extensionType); return; + + default: + case 6: + case 7: + case 10: + case 11: + case 14: + case 15: + HALT_UNALLOC; + } +} + +static void +dexLoadUnsignedImmediate (sim_cpu *cpu) +{ + /* assert instr[29,24] == 111_01 + instr[31,30] = size + instr[26] = V + instr[23,22] = opc + instr[21,10] = uimm12 : unsigned immediate offset + instr[9,5] = rn may be SP. */ + /* unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); */ + uint32_t V = uimm (aarch64_get_instr (cpu), 26,26); + uint32_t dispatch = ( (uimm (aarch64_get_instr (cpu), 31, 30) << 2) + | uimm (aarch64_get_instr (cpu), 23, 22)); + uint32_t imm = uimm (aarch64_get_instr (cpu), 21, 10); + + if (!V) + { + /* GReg operations. */ + switch (dispatch) + { + case 0: strb_abs (cpu, imm); return; + case 1: ldrb32_abs (cpu, imm); return; + case 2: ldrsb_abs (cpu, imm); return; + case 3: ldrsb32_abs (cpu, imm); return; + case 4: strh_abs (cpu, imm); return; + case 5: ldrh32_abs (cpu, imm); return; + case 6: ldrsh_abs (cpu, imm); return; + case 7: ldrsh32_abs (cpu, imm); return; + case 8: str32_abs (cpu, imm); return; + case 9: ldr32_abs (cpu, imm); return; + case 10: ldrsw_abs (cpu, imm); return; + case 12: str_abs (cpu, imm); return; + case 13: ldr_abs (cpu, imm); return; + case 14: prfm_abs (cpu, imm); return; + + default: + case 11: + case 15: + HALT_UNALLOC; + } + } + + /* FReg operations. */ + switch (dispatch) + { + case 3: fldrq_abs (cpu, imm); return; + case 9: fldrs_abs (cpu, imm); return; + case 13: fldrd_abs (cpu, imm); return; + + case 0: fstrb_abs (cpu, imm); return; + case 2: fstrq_abs (cpu, imm); return; + case 4: fstrh_abs (cpu, imm); return; + case 8: fstrs_abs (cpu, imm); return; + case 12: fstrd_abs (cpu, imm); return; + + case 1: /* LDR 8 bit FP. */ + case 5: /* LDR 8 bit FP. */ + HALT_NYI; + + default: + case 6: + case 7: + case 10: + case 11: + case 14: + case 15: + HALT_UNALLOC; + } +} + +static void +dexLoadExclusive (sim_cpu *cpu) +{ + /* assert instr[29:24] = 001000; + instr[31,30] = size + instr[23] = 0 if exclusive + instr[22] = L : 1 if load, 0 if store + instr[21] = 1 if pair + instr[20,16] = Rs + instr[15] = o0 : 1 if ordered + instr[14,10] = Rt2 + instr[9,5] = Rn + instr[4.0] = Rt. */ + + switch (uimm (aarch64_get_instr (cpu), 22, 21)) + { + case 2: ldxr (cpu); return; + case 0: stxr (cpu); return; + default: HALT_NYI; + } +} + +static void +dexLoadOther (sim_cpu *cpu) +{ + uint32_t dispatch; + + /* instr[29,25] = 111_0 + instr[24] == 0 ==> dispatch, 1 ==> ldst reg unsigned immediate + instr[21:11,10] is the secondary dispatch. */ + if (uimm (aarch64_get_instr (cpu), 24, 24)) + { + dexLoadUnsignedImmediate (cpu); + return; + } + + dispatch = ( (uimm (aarch64_get_instr (cpu), 21, 21) << 2) + | uimm (aarch64_get_instr (cpu), 11, 10)); + switch (dispatch) + { + case 0: dexLoadUnscaledImmediate (cpu); return; + case 1: dexLoadImmediatePrePost (cpu); return; + case 3: dexLoadImmediatePrePost (cpu); return; + case 6: dexLoadRegisterOffset (cpu); return; + + default: + case 2: + case 4: + case 5: + case 7: + HALT_NYI; + } +} + +static void +store_pair_u32 (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rd = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rm = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK); + + if ((rn == rd || rm == rd) && wb != NoWriteBack) + HALT_UNALLOC; /* ??? */ + + offset <<= 2; + + if (wb != Post) + address += offset; + + aarch64_set_mem_u32 (cpu, address, + aarch64_get_reg_u32 (cpu, rm, NO_SP)); + aarch64_set_mem_u32 (cpu, address + 4, + aarch64_get_reg_u32 (cpu, rn, NO_SP)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rd, SP_OK, address); +} + +static void +store_pair_u64 (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rd = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rm = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK); + + if ((rn == rd || rm == rd) && wb != NoWriteBack) + HALT_UNALLOC; /* ??? */ + + offset <<= 3; + + if (wb != Post) + address += offset; + + aarch64_set_mem_u64 (cpu, address, + aarch64_get_reg_u64 (cpu, rm, SP_OK)); + aarch64_set_mem_u64 (cpu, address + 8, + aarch64_get_reg_u64 (cpu, rn, SP_OK)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rd, SP_OK, address); +} + +static void +load_pair_u32 (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rd = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rm = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK); + + /* treat this as unalloc to make sure we don't do it. */ + if (rn == rm) + HALT_UNALLOC; + + offset <<= 2; + + if (wb != Post) + address += offset; + + aarch64_set_reg_u64 (cpu, rm, SP_OK, aarch64_get_mem_u32 (cpu, address)); + aarch64_set_reg_u64 (cpu, rn, SP_OK, aarch64_get_mem_u32 (cpu, address + 4)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rd, SP_OK, address); +} + +static void +load_pair_s32 (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rd = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rm = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK); + + /* Treat this as unalloc to make sure we don't do it. */ + if (rn == rm) + HALT_UNALLOC; + + offset <<= 2; + + if (wb != Post) + address += offset; + + aarch64_set_reg_s64 (cpu, rm, SP_OK, aarch64_get_mem_s32 (cpu, address)); + aarch64_set_reg_s64 (cpu, rn, SP_OK, aarch64_get_mem_s32 (cpu, address + 4)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rd, SP_OK, address); +} + +static void +load_pair_u64 (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rd = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rm = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK); + + /* Treat this as unalloc to make sure we don't do it. */ + if (rn == rm) + HALT_UNALLOC; + + offset <<= 3; + + if (wb != Post) + address += offset; + + aarch64_set_reg_u64 (cpu, rm, SP_OK, aarch64_get_mem_u64 (cpu, address)); + aarch64_set_reg_u64 (cpu, rn, SP_OK, aarch64_get_mem_u64 (cpu, address + 8)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rd, SP_OK, address); +} + +static void +dex_load_store_pair_gr (sim_cpu *cpu) +{ + /* instr[31,30] = size (10=> 64-bit, 01=> signed 32-bit, 00=> 32-bit) + instr[29,25] = instruction encoding: 101_0 + instr[26] = V : 1 if fp 0 if gp + instr[24,23] = addressing mode (10=> offset, 01=> post, 11=> pre) + instr[22] = load/store (1=> load) + instr[21,15] = signed, scaled, offset + instr[14,10] = Rn + instr[ 9, 5] = Rd + instr[ 4, 0] = Rm. */ + + uint32_t dispatch = ((uimm (aarch64_get_instr (cpu), 31, 30) << 3) + | uimm (aarch64_get_instr (cpu), 24, 22)); + int32_t offset = simm32 (aarch64_get_instr (cpu), 21, 15); + + switch (dispatch) + { + case 2: store_pair_u32 (cpu, offset, Post); return; + case 3: load_pair_u32 (cpu, offset, Post); return; + case 4: store_pair_u32 (cpu, offset, NoWriteBack); return; + case 5: load_pair_u32 (cpu, offset, NoWriteBack); return; + case 6: store_pair_u32 (cpu, offset, Pre); return; + case 7: load_pair_u32 (cpu, offset, Pre); return; + + case 11: load_pair_s32 (cpu, offset, Post); return; + case 13: load_pair_s32 (cpu, offset, NoWriteBack); return; + case 15: load_pair_s32 (cpu, offset, Pre); return; + + case 18: store_pair_u64 (cpu, offset, Post); return; + case 19: load_pair_u64 (cpu, offset, Post); return; + case 20: store_pair_u64 (cpu, offset, NoWriteBack); return; + case 21: load_pair_u64 (cpu, offset, NoWriteBack); return; + case 22: store_pair_u64 (cpu, offset, Pre); return; + case 23: load_pair_u64 (cpu, offset, Pre); return; + + default: + HALT_UNALLOC; + } +} + +static void +store_pair_float (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rd = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rm = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK); + + offset <<= 2; + + if (wb != Post) + address += offset; + + aarch64_set_mem_float (cpu, address, aarch64_get_FP_float (cpu, rm)); + aarch64_set_mem_float (cpu, address + 4, aarch64_get_FP_float (cpu, rn)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rd, SP_OK, address); +} + +static void +store_pair_double (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rd = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rm = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK); + + offset <<= 3; + + if (wb != Post) + address += offset; + + aarch64_set_mem_double (cpu, address, aarch64_get_FP_double (cpu, rm)); + aarch64_set_mem_double (cpu, address + 8, aarch64_get_FP_double (cpu, rn)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rd, SP_OK, address); +} + +static void +store_pair_long_double (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + FRegister a; + unsigned rn = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rd = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rm = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK); + + offset <<= 4; + + if (wb != Post) + address += offset; + + aarch64_get_FP_long_double (cpu, rm, & a); + aarch64_set_mem_long_double (cpu, address, a); + aarch64_get_FP_long_double (cpu, rn, & a); + aarch64_set_mem_long_double (cpu, address + 16, a); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rd, SP_OK, address); +} + +static void +load_pair_float (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rd = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rm = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK); + + if (rm == rn) + HALT_UNALLOC; + + offset <<= 2; + + if (wb != Post) + address += offset; + + aarch64_set_FP_float (cpu, rm, aarch64_get_mem_float (cpu, address)); + aarch64_set_FP_float (cpu, rn, aarch64_get_mem_float (cpu, address + 4)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rd, SP_OK, address); +} + +static void +load_pair_double (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rd = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rm = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK); + + if (rm == rn) + HALT_UNALLOC; + + offset <<= 3; + + if (wb != Post) + address += offset; + + aarch64_set_FP_double (cpu, rm, aarch64_get_mem_double (cpu, address)); + aarch64_set_FP_double (cpu, rn, aarch64_get_mem_double (cpu, address + 8)); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rd, SP_OK, address); +} + +static void +load_pair_long_double (sim_cpu *cpu, int32_t offset, WriteBack wb) +{ + FRegister a; + unsigned rn = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rd = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rm = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t address = aarch64_get_reg_u64 (cpu, rd, SP_OK); + + if (rm == rn) + HALT_UNALLOC; + + offset <<= 4; + + if (wb != Post) + address += offset; + + aarch64_get_mem_long_double (cpu, address, & a); + aarch64_set_FP_long_double (cpu, rm, a); + aarch64_get_mem_long_double (cpu, address + 16, & a); + aarch64_set_FP_long_double (cpu, rn, a); + + if (wb == Post) + address += offset; + + if (wb != NoWriteBack) + aarch64_set_reg_u64 (cpu, rd, SP_OK, address); +} + +static void +dex_load_store_pair_fp (sim_cpu *cpu) +{ + /* instr[31,30] = size (10=> 128-bit, 01=> 64-bit, 00=> 32-bit) + instr[29,25] = instruction encoding + instr[24,23] = addressing mode (10=> offset, 01=> post, 11=> pre) + instr[22] = load/store (1=> load) + instr[21,15] = signed, scaled, offset + instr[14,10] = Rn + instr[ 9, 5] = Rd + instr[ 4, 0] = Rm */ + + uint32_t dispatch = ((uimm (aarch64_get_instr (cpu), 31, 30) << 3) + | uimm (aarch64_get_instr (cpu), 24, 22)); + int32_t offset = simm32 (aarch64_get_instr (cpu), 21, 15); + + switch (dispatch) + { + case 2: store_pair_float (cpu, offset, Post); return; + case 3: load_pair_float (cpu, offset, Post); return; + case 4: store_pair_float (cpu, offset, NoWriteBack); return; + case 5: load_pair_float (cpu, offset, NoWriteBack); return; + case 6: store_pair_float (cpu, offset, Pre); return; + case 7: load_pair_float (cpu, offset, Pre); return; + + case 10: store_pair_double (cpu, offset, Post); return; + case 11: load_pair_double (cpu, offset, Post); return; + case 12: store_pair_double (cpu, offset, NoWriteBack); return; + case 13: load_pair_double (cpu, offset, NoWriteBack); return; + case 14: store_pair_double (cpu, offset, Pre); return; + case 15: load_pair_double (cpu, offset, Pre); return; + + case 18: store_pair_long_double (cpu, offset, Post); return; + case 19: load_pair_long_double (cpu, offset, Post); return; + case 20: store_pair_long_double (cpu, offset, NoWriteBack); return; + case 21: load_pair_long_double (cpu, offset, NoWriteBack); return; + case 22: store_pair_long_double (cpu, offset, Pre); return; + case 23: load_pair_long_double (cpu, offset, Pre); return; + + default: + HALT_UNALLOC; + } +} + +static inline unsigned +vec_reg (unsigned v, unsigned o) +{ + return (v + o) & 0x3F; +} + +/* Load multiple N-element structures to N consecutive registers. */ +static void +vec_load (sim_cpu *cpu, uint64_t address, unsigned N) +{ + int all = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned size = uimm (aarch64_get_instr (cpu), 11, 10); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + switch (size) + { + case 0: /* 8-bit operations. */ + if (all) + for (i = 0; i < (16 * N); i++) + aarch64_set_vec_u8 (cpu, vec_reg (vd, i >> 4), i & 15, + aarch64_get_mem_u8 (cpu, address + i)); + else + for (i = 0; i < (8 * N); i++) + aarch64_set_vec_u8 (cpu, vec_reg (vd, i >> 3), i & 7, + aarch64_get_mem_u8 (cpu, address + i)); + return; + + case 1: /* 16-bit operations. */ + if (all) + for (i = 0; i < (8 * N); i++) + aarch64_set_vec_u16 (cpu, vec_reg (vd, i >> 3), i & 7, + aarch64_get_mem_u16 (cpu, address + i * 2)); + else + for (i = 0; i < (4 * N); i++) + aarch64_set_vec_u16 (cpu, vec_reg (vd, i >> 2), i & 3, + aarch64_get_mem_u16 (cpu, address + i * 2)); + return; + + case 2: /* 32-bit operations. */ + if (all) + for (i = 0; i < (4 * N); i++) + aarch64_set_vec_u32 (cpu, vec_reg (vd, i >> 2), i & 3, + aarch64_get_mem_u32 (cpu, address + i * 4)); + else + for (i = 0; i < (2 * N); i++) + aarch64_set_vec_u32 (cpu, vec_reg (vd, i >> 1), i & 1, + aarch64_get_mem_u32 (cpu, address + i * 4)); + return; + + case 3: /* 64-bit operations. */ + if (all) + for (i = 0; i < (2 * N); i++) + aarch64_set_vec_u64 (cpu, vec_reg (vd, i >> 1), i & 1, + aarch64_get_mem_u64 (cpu, address + i * 8)); + else + for (i = 0; i < N; i++) + aarch64_set_vec_u64 (cpu, vec_reg (vd, i), 0, + aarch64_get_mem_u64 (cpu, address + i * 8)); + return; + + default: + HALT_UNREACHABLE; + } +} + +/* LD4: load multiple 4-element to four consecutive registers. */ +static void +LD4 (sim_cpu *cpu, uint64_t address) +{ + vec_load (cpu, address, 4); +} + +/* LD3: load multiple 3-element structures to three consecutive registers. */ +static void +LD3 (sim_cpu *cpu, uint64_t address) +{ + vec_load (cpu, address, 3); +} + +/* LD2: load multiple 2-element structures to two consecutive registers. */ +static void +LD2 (sim_cpu *cpu, uint64_t address) +{ + vec_load (cpu, address, 2); +} + +/* Load multiple 1-element structures into one register. */ +static void +LD1_1 (sim_cpu *cpu, uint64_t address) +{ + int all = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned size = uimm (aarch64_get_instr (cpu), 11, 10); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + switch (size) + { + case 0: + /* LD1 {Vd.16b}, addr, #16 */ + /* LD1 {Vd.8b}, addr, #8 */ + for (i = 0; i < (all ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, + aarch64_get_mem_u8 (cpu, address + i)); + return; + + case 1: + /* LD1 {Vd.8h}, addr, #16 */ + /* LD1 {Vd.4h}, addr, #8 */ + for (i = 0; i < (all ? 8 : 4); i++) + aarch64_set_vec_u16 (cpu, vd, i, + aarch64_get_mem_u16 (cpu, address + i * 2)); + return; + + case 2: + /* LD1 {Vd.4s}, addr, #16 */ + /* LD1 {Vd.2s}, addr, #8 */ + for (i = 0; i < (all ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, + aarch64_get_mem_u32 (cpu, address + i * 4)); + return; + + case 3: + /* LD1 {Vd.2d}, addr, #16 */ + /* LD1 {Vd.1d}, addr, #8 */ + for (i = 0; i < (all ? 2 : 1); i++) + aarch64_set_vec_u64 (cpu, vd, i, + aarch64_get_mem_u64 (cpu, address + i * 8)); + return; + + default: + HALT_UNREACHABLE; + } +} + +/* Load multiple 1-element structures into two registers. */ +static void +LD1_2 (sim_cpu *cpu, uint64_t address) +{ + /* FIXME: This algorithm is *exactly* the same as the LD2 version. + So why have two different instructions ? There must be something + wrong somewhere. */ + vec_load (cpu, address, 2); +} + +/* Load multiple 1-element structures into three registers. */ +static void +LD1_3 (sim_cpu *cpu, uint64_t address) +{ + /* FIXME: This algorithm is *exactly* the same as the LD3 version. + So why have two different instructions ? There must be something + wrong somewhere. */ + vec_load (cpu, address, 3); +} + +/* Load multiple 1-element structures into four registers. */ +static void +LD1_4 (sim_cpu *cpu, uint64_t address) +{ + /* FIXME: This algorithm is *exactly* the same as the LD4 version. + So why have two different instructions ? There must be something + wrong somewhere. */ + vec_load (cpu, address, 4); +} + +/* Store multiple N-element structures to N consecutive registers. */ +static void +vec_store (sim_cpu *cpu, uint64_t address, unsigned N) +{ + int all = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned size = uimm (aarch64_get_instr (cpu), 11, 10); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + switch (size) + { + case 0: /* 8-bit operations. */ + if (all) + for (i = 0; i < (16 * N); i++) + aarch64_set_mem_u8 + (cpu, address + i, + aarch64_get_vec_u8 (cpu, vec_reg (vd, i >> 4), i & 15)); + else + for (i = 0; i < (8 * N); i++) + aarch64_set_mem_u8 + (cpu, address + i, + aarch64_get_vec_u8 (cpu, vec_reg (vd, i >> 3), i & 7)); + return; + + case 1: /* 16-bit operations. */ + if (all) + for (i = 0; i < (8 * N); i++) + aarch64_set_mem_u16 + (cpu, address + i * 2, + aarch64_get_vec_u16 (cpu, vec_reg (vd, i >> 3), i & 7)); + else + for (i = 0; i < (4 * N); i++) + aarch64_set_mem_u16 + (cpu, address + i * 2, + aarch64_get_vec_u16 (cpu, vec_reg (vd, i >> 2), i & 3)); + return; + + case 2: /* 32-bit operations. */ + if (all) + for (i = 0; i < (4 * N); i++) + aarch64_set_mem_u32 + (cpu, address + i * 4, + aarch64_get_vec_u32 (cpu, vec_reg (vd, i >> 2), i & 3)); + else + for (i = 0; i < (2 * N); i++) + aarch64_set_mem_u32 + (cpu, address + i * 4, + aarch64_get_vec_u32 (cpu, vec_reg (vd, i >> 1), i & 1)); + return; + + case 3: /* 64-bit operations. */ + if (all) + for (i = 0; i < (2 * N); i++) + aarch64_set_mem_u64 + (cpu, address + i * 8, + aarch64_get_vec_u64 (cpu, vec_reg (vd, i >> 1), i & 1)); + else + for (i = 0; i < N; i++) + aarch64_set_mem_u64 + (cpu, address + i * 8, + aarch64_get_vec_u64 (cpu, vec_reg (vd, i), 0)); + return; + + default: + HALT_UNREACHABLE; + } +} + +/* Store multiple 4-element structure to four consecutive registers. */ +static void +ST4 (sim_cpu *cpu, uint64_t address) +{ + vec_store (cpu, address, 4); +} + +/* Store multiple 3-element structures to three consecutive registers. */ +static void +ST3 (sim_cpu *cpu, uint64_t address) +{ + vec_store (cpu, address, 3); +} + +/* Store multiple 2-element structures to two consecutive registers. */ +static void +ST2 (sim_cpu *cpu, uint64_t address) +{ + vec_store (cpu, address, 2); +} + +/* Store multiple 1-element structures into one register. */ +static void +ST1_1 (sim_cpu *cpu, uint64_t address) +{ + int all = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned size = uimm (aarch64_get_instr (cpu), 11, 10); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned i; + + switch (size) + { + case 0: + for (i = 0; i < (all ? 16 : 8); i++) + aarch64_set_mem_u8 (cpu, address + i, + aarch64_get_vec_u8 (cpu, vd, i)); + return; + + case 1: + for (i = 0; i < (all ? 8 : 4); i++) + aarch64_set_mem_u16 (cpu, address + i * 2, + aarch64_get_vec_u16 (cpu, vd, i)); + return; + + case 2: + for (i = 0; i < (all ? 4 : 2); i++) + aarch64_set_mem_u32 (cpu, address + i * 4, + aarch64_get_vec_u32 (cpu, vd, i)); + return; + + case 3: + for (i = 0; i < (all ? 2 : 1); i++) + aarch64_set_mem_u64 (cpu, address + i * 8, + aarch64_get_vec_u64 (cpu, vd, i)); + return; + + default: + HALT_UNREACHABLE; + } +} + +/* Store multiple 1-element structures into two registers. */ +static void +ST1_2 (sim_cpu *cpu, uint64_t address) +{ + /* FIXME: This algorithm is *exactly* the same as the ST2 version. + So why have two different instructions ? There must be + something wrong somewhere. */ + vec_store (cpu, address, 2); +} + +/* Store multiple 1-element structures into three registers. */ +static void +ST1_3 (sim_cpu *cpu, uint64_t address) +{ + /* FIXME: This algorithm is *exactly* the same as the ST3 version. + So why have two different instructions ? There must be + something wrong somewhere. */ + vec_store (cpu, address, 3); +} + +/* Store multiple 1-element structures into four registers. */ +static void +ST1_4 (sim_cpu *cpu, uint64_t address) +{ + /* FIXME: This algorithm is *exactly* the same as the ST4 version. + So why have two different instructions ? There must be + something wrong somewhere. */ + vec_store (cpu, address, 4); +} + +static void +do_vec_LDnR (sim_cpu *cpu, uint64_t address) +{ + /* instr[31] = 0 + instr[30] = element selector 0=>half, 1=>all elements + instr[29,24] = 00 1101 + instr[23] = 0=>simple, 1=>post + instr[22] = 1 + instr[21] = width: LD1R-or-LD3R (0) / LD2R-or-LD4R (1) + instr[20,16] = 0 0000 (simple), Vinc (reg-post-inc, no SP), + 11111 (immediate post inc) + instr[15,14] = 11 + instr[13] = width: LD1R-or-LD2R (0) / LD3R-or-LD4R (1) + instr[12] = 0 + instr[11,10] = element size 00=> byte(b), 01=> half(h), + 10=> word(s), 11=> double(d) + instr[9,5] = address + instr[4,0] = Vd */ + + unsigned full = uimm (aarch64_get_instr (cpu), 30, 30); + unsigned vd = uimm (aarch64_get_instr (cpu), 4, 0); + unsigned size = uimm (aarch64_get_instr (cpu), 11, 10); + int i; + + NYI_assert (29, 24, 0x0D); + NYI_assert (22, 22, 1); + NYI_assert (15, 14, 3); + NYI_assert (12, 12, 0); + + switch ((uimm (aarch64_get_instr (cpu), 13, 13) << 1) + | uimm (aarch64_get_instr (cpu), 21, 21)) + { + case 0: /* LD1R. */ + switch (size) + { + case 0: + { + uint8_t val = aarch64_get_mem_u8 (cpu, address); + for (i = 0; i < (full ? 16 : 8); i++) + aarch64_set_vec_u8 (cpu, vd, i, val); + break; + } + + case 1: + { + uint16_t val = aarch64_get_mem_u16 (cpu, address); + for (i = 0; i < (full ? 8 : 4); i++) + aarch64_set_vec_u16 (cpu, vd, i, val); + break; + } + + case 2: + { + uint32_t val = aarch64_get_mem_u32 (cpu, address); + for (i = 0; i < (full ? 4 : 2); i++) + aarch64_set_vec_u32 (cpu, vd, i, val); + break; + } + + case 3: + { + uint64_t val = aarch64_get_mem_u64 (cpu, address); + for (i = 0; i < (full ? 2 : 1); i++) + aarch64_set_vec_u64 (cpu, vd, i, val); + break; + } + + default: + HALT_UNALLOC; + } + break; + + case 1: /* LD2R. */ + switch (size) + { + case 0: + { + uint8_t val1 = aarch64_get_mem_u8 (cpu, address); + uint8_t val2 = aarch64_get_mem_u8 (cpu, address + 1); + + for (i = 0; i < (full ? 16 : 8); i++) + { + aarch64_set_vec_u8 (cpu, vd, 0, val1); + aarch64_set_vec_u8 (cpu, vd + 1, 0, val2); + } + break; + } + + case 1: + { + uint16_t val1 = aarch64_get_mem_u16 (cpu, address); + uint16_t val2 = aarch64_get_mem_u16 (cpu, address + 2); + + for (i = 0; i < (full ? 8 : 4); i++) + { + aarch64_set_vec_u16 (cpu, vd, 0, val1); + aarch64_set_vec_u16 (cpu, vd + 1, 0, val2); + } + break; + } + + case 2: + { + uint32_t val1 = aarch64_get_mem_u32 (cpu, address); + uint32_t val2 = aarch64_get_mem_u32 (cpu, address + 4); + + for (i = 0; i < (full ? 4 : 2); i++) + { + aarch64_set_vec_u32 (cpu, vd, 0, val1); + aarch64_set_vec_u32 (cpu, vd + 1, 0, val2); + } + break; + } + + case 3: + { + uint64_t val1 = aarch64_get_mem_u64 (cpu, address); + uint64_t val2 = aarch64_get_mem_u64 (cpu, address + 8); + + for (i = 0; i < (full ? 2 : 1); i++) + { + aarch64_set_vec_u64 (cpu, vd, 0, val1); + aarch64_set_vec_u64 (cpu, vd + 1, 0, val2); + } + break; + } + + default: + HALT_UNALLOC; + } + break; + + case 2: /* LD3R. */ + switch (size) + { + case 0: + { + uint8_t val1 = aarch64_get_mem_u8 (cpu, address); + uint8_t val2 = aarch64_get_mem_u8 (cpu, address + 1); + uint8_t val3 = aarch64_get_mem_u8 (cpu, address + 2); + + for (i = 0; i < (full ? 16 : 8); i++) + { + aarch64_set_vec_u8 (cpu, vd, 0, val1); + aarch64_set_vec_u8 (cpu, vd + 1, 0, val2); + aarch64_set_vec_u8 (cpu, vd + 2, 0, val3); + } + } + break; + + case 1: + { + uint32_t val1 = aarch64_get_mem_u16 (cpu, address); + uint32_t val2 = aarch64_get_mem_u16 (cpu, address + 2); + uint32_t val3 = aarch64_get_mem_u16 (cpu, address + 4); + + for (i = 0; i < (full ? 8 : 4); i++) + { + aarch64_set_vec_u16 (cpu, vd, 0, val1); + aarch64_set_vec_u16 (cpu, vd + 1, 0, val2); + aarch64_set_vec_u16 (cpu, vd + 2, 0, val3); + } + } + break; + + case 2: + { + uint32_t val1 = aarch64_get_mem_u32 (cpu, address); + uint32_t val2 = aarch64_get_mem_u32 (cpu, address + 4); + uint32_t val3 = aarch64_get_mem_u32 (cpu, address + 8); + + for (i = 0; i < (full ? 4 : 2); i++) + { + aarch64_set_vec_u32 (cpu, vd, 0, val1); + aarch64_set_vec_u32 (cpu, vd + 1, 0, val2); + aarch64_set_vec_u32 (cpu, vd + 2, 0, val3); + } + } + break; + + case 3: + { + uint64_t val1 = aarch64_get_mem_u64 (cpu, address); + uint64_t val2 = aarch64_get_mem_u64 (cpu, address + 8); + uint64_t val3 = aarch64_get_mem_u64 (cpu, address + 16); + + for (i = 0; i < (full ? 2 : 1); i++) + { + aarch64_set_vec_u64 (cpu, vd, 0, val1); + aarch64_set_vec_u64 (cpu, vd + 1, 0, val2); + aarch64_set_vec_u64 (cpu, vd + 2, 0, val3); + } + } + break; + + default: + HALT_UNALLOC; + } + break; + + case 3: /* LD4R. */ + switch (size) + { + case 0: + { + uint8_t val1 = aarch64_get_mem_u8 (cpu, address); + uint8_t val2 = aarch64_get_mem_u8 (cpu, address + 1); + uint8_t val3 = aarch64_get_mem_u8 (cpu, address + 2); + uint8_t val4 = aarch64_get_mem_u8 (cpu, address + 3); + + for (i = 0; i < (full ? 16 : 8); i++) + { + aarch64_set_vec_u8 (cpu, vd, 0, val1); + aarch64_set_vec_u8 (cpu, vd + 1, 0, val2); + aarch64_set_vec_u8 (cpu, vd + 2, 0, val3); + aarch64_set_vec_u8 (cpu, vd + 3, 0, val4); + } + } + break; + + case 1: + { + uint32_t val1 = aarch64_get_mem_u16 (cpu, address); + uint32_t val2 = aarch64_get_mem_u16 (cpu, address + 2); + uint32_t val3 = aarch64_get_mem_u16 (cpu, address + 4); + uint32_t val4 = aarch64_get_mem_u16 (cpu, address + 6); + + for (i = 0; i < (full ? 8 : 4); i++) + { + aarch64_set_vec_u16 (cpu, vd, 0, val1); + aarch64_set_vec_u16 (cpu, vd + 1, 0, val2); + aarch64_set_vec_u16 (cpu, vd + 2, 0, val3); + aarch64_set_vec_u16 (cpu, vd + 3, 0, val4); + } + } + break; + + case 2: + { + uint32_t val1 = aarch64_get_mem_u32 (cpu, address); + uint32_t val2 = aarch64_get_mem_u32 (cpu, address + 4); + uint32_t val3 = aarch64_get_mem_u32 (cpu, address + 8); + uint32_t val4 = aarch64_get_mem_u32 (cpu, address + 12); + + for (i = 0; i < (full ? 4 : 2); i++) + { + aarch64_set_vec_u32 (cpu, vd, 0, val1); + aarch64_set_vec_u32 (cpu, vd + 1, 0, val2); + aarch64_set_vec_u32 (cpu, vd + 2, 0, val3); + aarch64_set_vec_u32 (cpu, vd + 3, 0, val4); + } + } + break; + + case 3: + { + uint64_t val1 = aarch64_get_mem_u64 (cpu, address); + uint64_t val2 = aarch64_get_mem_u64 (cpu, address + 8); + uint64_t val3 = aarch64_get_mem_u64 (cpu, address + 16); + uint64_t val4 = aarch64_get_mem_u64 (cpu, address + 24); + + for (i = 0; i < (full ? 2 : 1); i++) + { + aarch64_set_vec_u64 (cpu, vd, 0, val1); + aarch64_set_vec_u64 (cpu, vd + 1, 0, val2); + aarch64_set_vec_u64 (cpu, vd + 2, 0, val3); + aarch64_set_vec_u64 (cpu, vd + 3, 0, val4); + } + } + break; + + default: + HALT_UNALLOC; + } + break; + + default: + HALT_UNALLOC; + } +} + +static void +do_vec_load_store (sim_cpu *cpu) +{ + /* {LD|ST}<N> {Vd..Vd+N}, vaddr + + instr[31] = 0 + instr[30] = element selector 0=>half, 1=>all elements + instr[29,25] = 00110 + instr[24] = ? + instr[23] = 0=>simple, 1=>post + instr[22] = 0=>store, 1=>load + instr[21] = 0 (LDn) / small(0)-large(1) selector (LDnR) + instr[20,16] = 00000 (simple), Vinc (reg-post-inc, no SP), + 11111 (immediate post inc) + instr[15,12] = elements and destinations. eg for load: + 0000=>LD4 => load multiple 4-element to + four consecutive registers + 0100=>LD3 => load multiple 3-element to + three consecutive registers + 1000=>LD2 => load multiple 2-element to + two consecutive registers + 0010=>LD1 => load multiple 1-element to + four consecutive registers + 0110=>LD1 => load multiple 1-element to + three consecutive registers + 1010=>LD1 => load multiple 1-element to + two consecutive registers + 0111=>LD1 => load multiple 1-element to + one register + 1100=>LDR1,LDR2 + 1110=>LDR3,LDR4 + instr[11,10] = element size 00=> byte(b), 01=> half(h), + 10=> word(s), 11=> double(d) + instr[9,5] = Vn, can be SP + instr[4,0] = Vd */ + + int post; + int load; + unsigned vn; + uint64_t address; + int type; + + if (uimm (aarch64_get_instr (cpu), 31, 31) != 0 + || uimm (aarch64_get_instr (cpu), 29, 25) != 0x06) + HALT_NYI; + + type = uimm (aarch64_get_instr (cpu), 15, 12); + if (type != 0xE && type != 0xE && uimm (aarch64_get_instr (cpu), 21, 21) != 0) + HALT_NYI; + + post = uimm (aarch64_get_instr (cpu), 23, 23); + load = uimm (aarch64_get_instr (cpu), 22, 22); + vn = uimm (aarch64_get_instr (cpu), 9, 5); + address = aarch64_get_reg_u64 (cpu, vn, SP_OK); + + if (post) + { + unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16); + + if (vm == R31) + { + unsigned sizeof_operation; + + switch (type) + { + case 0: sizeof_operation = 32; break; + case 4: sizeof_operation = 24; break; + case 8: sizeof_operation = 16; break; + + case 0xC: + sizeof_operation = uimm (aarch64_get_instr (cpu), 21, 21) ? 2 : 1; + sizeof_operation <<= uimm (aarch64_get_instr (cpu), 11, 10); + break; + + case 0xE: + sizeof_operation = uimm (aarch64_get_instr (cpu), 21, 21) ? 8 : 4; + sizeof_operation <<= uimm (aarch64_get_instr (cpu), 11, 10); + break; + + case 2: + case 6: + case 10: + case 7: + sizeof_operation = 2 << uimm (aarch64_get_instr (cpu), 11, 10); + break; + + default: + HALT_UNALLOC; + } + + if (uimm (aarch64_get_instr (cpu), 30, 30)) + sizeof_operation *= 2; + + aarch64_set_reg_u64 (cpu, vn, SP_OK, address + sizeof_operation); + } + else + aarch64_set_reg_u64 (cpu, vn, SP_OK, + address + aarch64_get_reg_u64 (cpu, vm, NO_SP)); + } + else + { + NYI_assert (20, 16, 0); + } + + if (load) + { + switch (type) + { + case 0: LD4 (cpu, address); return; + case 4: LD3 (cpu, address); return; + case 8: LD2 (cpu, address); return; + case 2: LD1_4 (cpu, address); return; + case 6: LD1_3 (cpu, address); return; + case 10: LD1_2 (cpu, address); return; + case 7: LD1_1 (cpu, address); return; + + case 0xE: + case 0xC: do_vec_LDnR (cpu, address); return; + + default: + HALT_NYI; + } + } + + /* Stores. */ + switch (type) + { + case 0: ST4 (cpu, address); return; + case 4: ST3 (cpu, address); return; + case 8: ST2 (cpu, address); return; + case 2: ST1_4 (cpu, address); return; + case 6: ST1_3 (cpu, address); return; + case 10: ST1_2 (cpu, address); return; + case 7: ST1_1 (cpu, address); return; + default: + HALT_NYI; + } +} + +static void +dexLdSt (sim_cpu *cpu) +{ + /* uint32_t group = dispatchGroup (aarch64_get_instr (cpu)); + assert group == GROUP_LDST_0100 || group == GROUP_LDST_0110 || + group == GROUP_LDST_1100 || group == GROUP_LDST_1110 + bits [29,28:26] of a LS are the secondary dispatch vector. */ + uint32_t group2 = dispatchLS (aarch64_get_instr (cpu)); + + switch (group2) + { + case LS_EXCL_000: + dexLoadExclusive (cpu); return; + + case LS_LIT_010: + case LS_LIT_011: + dexLoadLiteral (cpu); return; + + case LS_OTHER_110: + case LS_OTHER_111: + dexLoadOther (cpu); return; + + case LS_ADVSIMD_001: + do_vec_load_store (cpu); return; + + case LS_PAIR_100: + dex_load_store_pair_gr (cpu); return; + + case LS_PAIR_101: + dex_load_store_pair_fp (cpu); return; + + default: + /* Should never reach here. */ + HALT_NYI; + } +} + +/* Specific decode and execute for group Data Processing Register. */ + +static void +dexLogicalShiftedRegister (sim_cpu *cpu) +{ + /* assert instr[28:24] = 01010 + instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[30,29:21] = op,N : 000 ==> AND, 001 ==> BIC, + 010 ==> ORR, 011 ==> ORN + 100 ==> EOR, 101 ==> EON, + 110 ==> ANDS, 111 ==> BICS + instr[23,22] = shift : 0 ==> LSL, 1 ==> LSR, 2 ==> ASR, 3 ==> ROR + instr[15,10] = count : must be 0xxxxx for 32 bit + instr[9,5] = Rn + instr[4,0] = Rd */ + + /* unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); */ + uint32_t dispatch; + Shift shiftType; + uint32_t size = uimm (aarch64_get_instr (cpu), 31, 31); + + /* 32 bit operations must have count[5] = 0. */ + /* or else we have an UNALLOC. */ + uint32_t count = uimm (aarch64_get_instr (cpu), 15, 10); + + if (!size && uimm (count, 5, 5)) + HALT_UNALLOC; + + shiftType = shift (aarch64_get_instr (cpu), 22); + + /* dispatch on size:op:N i.e aarch64_get_instr (cpu)[31,29:21]. */ + dispatch = ( (uimm (aarch64_get_instr (cpu), 31, 29) << 1) + | uimm (aarch64_get_instr (cpu), 21, 21)); + + switch (dispatch) + { + case 0: and32_shift (cpu, shiftType, count); return; + case 1: bic32_shift (cpu, shiftType, count); return; + case 2: orr32_shift (cpu, shiftType, count); return; + case 3: orn32_shift (cpu, shiftType, count); return; + case 4: eor32_shift (cpu, shiftType, count); return; + case 5: eon32_shift (cpu, shiftType, count); return; + case 6: ands32_shift (cpu, shiftType, count); return; + case 7: bics32_shift (cpu, shiftType, count); return; + case 8: and64_shift (cpu, shiftType, count); return; + case 9: bic64_shift (cpu, shiftType, count); return; + case 10:orr64_shift (cpu, shiftType, count); return; + case 11:orn64_shift (cpu, shiftType, count); return; + case 12:eor64_shift (cpu, shiftType, count); return; + case 13:eon64_shift (cpu, shiftType, count); return; + case 14:ands64_shift (cpu, shiftType, count); return; + case 15:bics64_shift (cpu, shiftType, count); return; + default: HALT_UNALLOC; + } +} + +/* 32 bit conditional select. */ +static void +csel32 (sim_cpu *cpu, CondCode cc) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + testConditionCode (cpu, cc) + ? aarch64_get_reg_u32 (cpu, rn, NO_SP) + : aarch64_get_reg_u32 (cpu, rm, NO_SP)); +} + +/* 64 bit conditional select. */ +static void +csel64 (sim_cpu *cpu, CondCode cc) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + testConditionCode (cpu, cc) + ? aarch64_get_reg_u64 (cpu, rn, NO_SP) + : aarch64_get_reg_u64 (cpu, rm, NO_SP)); +} + +/* 32 bit conditional increment. */ +static void +csinc32 (sim_cpu *cpu, CondCode cc) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + testConditionCode (cpu, cc) + ? aarch64_get_reg_u32 (cpu, rn, NO_SP) + : aarch64_get_reg_u32 (cpu, rm, NO_SP) + 1); +} + +/* 64 bit conditional increment. */ +static void +csinc64 (sim_cpu *cpu, CondCode cc) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + testConditionCode (cpu, cc) + ? aarch64_get_reg_u64 (cpu, rn, NO_SP) + : aarch64_get_reg_u64 (cpu, rm, NO_SP) + 1); +} + +/* 32 bit conditional invert. */ +static void +csinv32 (sim_cpu *cpu, CondCode cc) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + testConditionCode (cpu, cc) + ? aarch64_get_reg_u32 (cpu, rn, NO_SP) + : ~ aarch64_get_reg_u32 (cpu, rm, NO_SP)); +} + +/* 64 bit conditional invert. */ +static void +csinv64 (sim_cpu *cpu, CondCode cc) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + testConditionCode (cpu, cc) + ? aarch64_get_reg_u64 (cpu, rn, NO_SP) + : ~ aarch64_get_reg_u64 (cpu, rm, NO_SP)); +} + +/* 32 bit conditional negate. */ +static void +csneg32 (sim_cpu *cpu, CondCode cc) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + testConditionCode (cpu, cc) + ? aarch64_get_reg_u32 (cpu, rn, NO_SP) + : - aarch64_get_reg_u32 (cpu, rm, NO_SP)); +} + +/* 64 bit conditional negate. */ +static void +csneg64 (sim_cpu *cpu, CondCode cc) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + testConditionCode (cpu, cc) + ? aarch64_get_reg_u64 (cpu, rn, NO_SP) + : - aarch64_get_reg_u64 (cpu, rm, NO_SP)); +} + +static void +dexCondSelect (sim_cpu *cpu) +{ + /* assert instr[28,21] = 11011011 + instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[30:11,10] = op : 000 ==> CSEL, 001 ==> CSINC, + 100 ==> CSINV, 101 ==> CSNEG, + _1_ ==> UNALLOC + instr[29] = S : 0 ==> ok, 1 ==> UNALLOC + instr[15,12] = cond + instr[29] = S : 0 ==> ok, 1 ==> UNALLOC */ + + CondCode cc; + uint32_t dispatch; + uint32_t S = uimm (aarch64_get_instr (cpu), 29, 29); + uint32_t op2 = uimm (aarch64_get_instr (cpu), 11, 10); + + if (S == 1) + HALT_UNALLOC; + + if (op2 & 0x2) + HALT_UNALLOC; + + cc = condcode (aarch64_get_instr (cpu), 12); + dispatch = ((uimm (aarch64_get_instr (cpu), 31, 30) << 1) | op2); + + switch (dispatch) + { + case 0: csel32 (cpu, cc); return; + case 1: csinc32 (cpu, cc); return; + case 2: csinv32 (cpu, cc); return; + case 3: csneg32 (cpu, cc); return; + case 4: csel64 (cpu, cc); return; + case 5: csinc64 (cpu, cc); return; + case 6: csinv64 (cpu, cc); return; + case 7: csneg64 (cpu, cc); return; + default: HALT_UNALLOC; + } +} + +/* Some helpers for counting leading 1 or 0 bits. */ + +/* Counts the number of leading bits which are the same + in a 32 bit value in the range 1 to 32. */ +static uint32_t +leading32 (uint32_t value) +{ + int32_t mask= 0xffff0000; + uint32_t count= 16; /* Counts number of bits set in mask. */ + uint32_t lo = 1; /* Lower bound for number of sign bits. */ + uint32_t hi = 32; /* Upper bound for number of sign bits. */ + + while (lo + 1 < hi) + { + int32_t test = (value & mask); + + if (test == 0 || test == mask) + { + lo = count; + count = (lo + hi) / 2; + mask >>= (count - lo); + } + else + { + hi = count; + count = (lo + hi) / 2; + mask <<= hi - count; + } + } + + if (lo != hi) + { + int32_t test; + + mask >>= 1; + test = (value & mask); + + if (test == 0 || test == mask) + count = hi; + else + count = lo; + } + + return count; +} + +/* Counts the number of leading bits which are the same + in a 64 bit value in the range 1 to 64. */ +static uint64_t +leading64 (uint64_t value) +{ + int64_t mask= 0xffffffff00000000LL; + uint64_t count = 32; /* Counts number of bits set in mask. */ + uint64_t lo = 1; /* Lower bound for number of sign bits. */ + uint64_t hi = 64; /* Upper bound for number of sign bits. */ + + while (lo + 1 < hi) + { + int64_t test = (value & mask); + + if (test == 0 || test == mask) + { + lo = count; + count = (lo + hi) / 2; + mask >>= (count - lo); + } + else + { + hi = count; + count = (lo + hi) / 2; + mask <<= hi - count; + } + } + + if (lo != hi) + { + int64_t test; + + mask >>= 1; + test = (value & mask); + + if (test == 0 || test == mask) + count = hi; + else + count = lo; + } + + return count; +} + +/* Bit operations. */ +/* N.B register args may not be SP. */ + +/* 32 bit count leading sign bits. */ +static void +cls32 (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + /* N.B. the result needs to exclude the leading bit. */ + aarch64_set_reg_u64 + (cpu, rd, NO_SP, leading32 (aarch64_get_reg_u32 (cpu, rn, NO_SP)) - 1); +} + +/* 64 bit count leading sign bits. */ +static void +cls64 (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + /* N.B. the result needs to exclude the leading bit. */ + aarch64_set_reg_u64 + (cpu, rd, NO_SP, leading64 (aarch64_get_reg_u64 (cpu, rn, NO_SP)) - 1); +} + +/* 32 bit count leading zero bits. */ +static void +clz32 (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP); + + /* if the sign (top) bit is set then the count is 0. */ + if (pick32 (value, 31, 31)) + aarch64_set_reg_u64 (cpu, rd, NO_SP, 0L); + else + aarch64_set_reg_u64 (cpu, rd, NO_SP, leading32 (value)); +} + +/* 64 bit count leading zero bits. */ +static void +clz64 (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP); + + /* if the sign (top) bit is set then the count is 0. */ + if (pick64 (value, 63, 63)) + aarch64_set_reg_u64 (cpu, rd, NO_SP, 0L); + else + aarch64_set_reg_u64 (cpu, rd, NO_SP, leading64 (value)); +} + +/* 32 bit reverse bits. */ +static void +rbit32 (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP); + uint32_t result = 0; + int i; + + for (i = 0; i < 32; i++) + { + result <<= 1; + result |= (value & 1); + value >>= 1; + } + aarch64_set_reg_u64 (cpu, rd, NO_SP, result); +} + +/* 64 bit reverse bits. */ +static void +rbit64 (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP); + uint64_t result = 0; + int i; + + for (i = 0; i < 64; i++) + { + result <<= 1; + result |= (value & 1L); + value >>= 1; + } + aarch64_set_reg_u64 (cpu, rd, NO_SP, result); +} + +/* 32 bit reverse bytes. */ +static void +rev32 (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP); + uint32_t result = 0; + int i; + + for (i = 0; i < 4; i++) + { + result <<= 8; + result |= (value & 0xff); + value >>= 8; + } + aarch64_set_reg_u64 (cpu, rd, NO_SP, result); +} + +/* 64 bit reverse bytes. */ +static void +rev64 (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP); + uint64_t result = 0; + int i; + + for (i = 0; i < 8; i++) + { + result <<= 8; + result |= (value & 0xffULL); + value >>= 8; + } + aarch64_set_reg_u64 (cpu, rd, NO_SP, result); +} + +/* 32 bit reverse shorts. */ +/* N.B.this reverses the order of the bytes in each half word. */ +static void +revh32 (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint32_t value = aarch64_get_reg_u32 (cpu, rn, NO_SP); + uint32_t result = 0; + int i; + + for (i = 0; i < 2; i++) + { + result <<= 8; + result |= (value & 0x00ff00ff); + value >>= 8; + } + aarch64_set_reg_u64 (cpu, rd, NO_SP, result); +} + +/* 64 bit reverse shorts. */ +/* N.B.this reverses the order of the bytes in each half word. */ +static void +revh64 (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + uint64_t value = aarch64_get_reg_u64 (cpu, rn, NO_SP); + uint64_t result = 0; + int i; + + for (i = 0; i < 2; i++) + { + result <<= 8; + result |= (value & 0x00ff00ff00ff00ffULL); + value >>= 8; + } + aarch64_set_reg_u64 (cpu, rd, NO_SP, result); +} + +static void +dexDataProc1Source (sim_cpu *cpu) +{ + /* assert instr[30] == 1 + aarch64_get_instr (cpu)[28,21] == 111010110 + instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[29] = S : 0 ==> ok, 1 ==> UNALLOC + instr[20,16] = opcode2 : 00000 ==> ok, ow ==> UNALLOC + instr[15,10] = opcode : 000000 ==> RBIT, 000001 ==> REV16, + 000010 ==> REV, 000011 ==> UNALLOC + 000100 ==> CLZ, 000101 ==> CLS + ow ==> UNALLOC + instr[9,5] = rn : may not be SP + instr[4,0] = rd : may not be SP. */ + + uint32_t S = uimm (aarch64_get_instr (cpu), 29, 29); + uint32_t opcode2 = uimm (aarch64_get_instr (cpu), 20, 16); + uint32_t opcode = uimm (aarch64_get_instr (cpu), 15, 10); + uint32_t dispatch = ((uimm (aarch64_get_instr (cpu), 31, 31) << 3) | opcode); + + if (S == 1) + HALT_UNALLOC; + + if (opcode2 != 0) + HALT_UNALLOC; + + if (opcode & 0x38) + HALT_UNALLOC; + + switch (dispatch) + { + case 0: rbit32 (cpu); return; + case 1: revh32 (cpu); return; + case 2: rev32 (cpu); return; + case 4: clz32 (cpu); return; + case 5: cls32 (cpu); return; + case 8: rbit64 (cpu); return; + case 9: revh64 (cpu); return; + case 10:rev32 (cpu); return; + case 11:rev64 (cpu); return; + case 12:clz64 (cpu); return; + case 13:cls64 (cpu); return; + default: HALT_UNALLOC; + } +} + +/* Variable shift. + Shifts by count supplied in register. + N.B register args may not be SP. + These all use the shifted auxiliary function for + simplicity and clarity. Writing the actual shift + inline would avoid a branch and so be faster but + would also necessitate getting signs right. */ + +/* 32 bit arithmetic shift right. */ +static void +asrv32 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, + shifted32 (aarch64_get_reg_u32 (cpu, rn, NO_SP), ASR, + (aarch64_get_reg_u32 (cpu, rm, NO_SP) & 0x1f))); +} + +/* 64 bit arithmetic shift right. */ +static void +asrv64 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, + shifted64 (aarch64_get_reg_u64 (cpu, rn, NO_SP), ASR, + (aarch64_get_reg_u64 (cpu, rm, NO_SP) & 0x3f))); +} + +/* 32 bit logical shift left. */ +static void +lslv32 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, + shifted32 (aarch64_get_reg_u32 (cpu, rn, NO_SP), LSL, + (aarch64_get_reg_u32 (cpu, rm, NO_SP) & 0x1f))); +} + +/* 64 bit arithmetic shift left. */ +static void +lslv64 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, + shifted64 (aarch64_get_reg_u64 (cpu, rn, NO_SP), LSL, + (aarch64_get_reg_u64 (cpu, rm, NO_SP) & 0x3f))); +} + +/* 32 bit logical shift right. */ +static void +lsrv32 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, + shifted32 (aarch64_get_reg_u32 (cpu, rn, NO_SP), LSR, + (aarch64_get_reg_u32 (cpu, rm, NO_SP) & 0x1f))); +} + +/* 64 bit logical shift right. */ +static void +lsrv64 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, + shifted64 (aarch64_get_reg_u64 (cpu, rn, NO_SP), LSR, + (aarch64_get_reg_u64 (cpu, rm, NO_SP) & 0x3f))); +} + +/* 32 bit rotate right. */ +static void +rorv32 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, + shifted32 (aarch64_get_reg_u32 (cpu, rn, NO_SP), ROR, + (aarch64_get_reg_u32 (cpu, rm, NO_SP) & 0x1f))); +} + +/* 64 bit rotate right. */ +static void +rorv64 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, + shifted64 (aarch64_get_reg_u64 (cpu, rn, NO_SP), ROR, + (aarch64_get_reg_u64 (cpu, rm, NO_SP) & 0x3f))); +} + + +/* divide. */ + +/* 32 bit signed divide. */ +static void +cpuiv32 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + /* N.B. the pseudo-code does the divide using 64 bit data. */ + /* TODO : check that this rounds towards zero as required. */ + int64_t dividend = aarch64_get_reg_s32 (cpu, rn, NO_SP); + int64_t divisor = aarch64_get_reg_s32 (cpu, rm, NO_SP); + + aarch64_set_reg_s64 (cpu, rd, NO_SP, + divisor ? ((int32_t) (dividend / divisor)) : 0); +} + +/* 64 bit signed divide. */ +static void +cpuiv64 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + /* TODO : check that this rounds towards zero as required. */ + int64_t divisor = aarch64_get_reg_s64 (cpu, rm, NO_SP); + + aarch64_set_reg_s64 + (cpu, rd, NO_SP, + divisor ? (aarch64_get_reg_s64 (cpu, rn, NO_SP) / divisor) : 0); +} + +/* 32 bit unsigned divide. */ +static void +udiv32 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + /* N.B. the pseudo-code does the divide using 64 bit data. */ + uint64_t dividend = aarch64_get_reg_u32 (cpu, rn, NO_SP); + uint64_t divisor = aarch64_get_reg_u32 (cpu, rm, NO_SP); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + divisor ? (uint32_t) (dividend / divisor) : 0); +} + +/* 64 bit unsigned divide. */ +static void +udiv64 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + /* TODO : check that this rounds towards zero as required. */ + uint64_t divisor = aarch64_get_reg_u64 (cpu, rm, NO_SP); + + aarch64_set_reg_u64 + (cpu, rd, NO_SP, + divisor ? (aarch64_get_reg_u64 (cpu, rn, NO_SP) / divisor) : 0); +} + +static void +dexDataProc2Source (sim_cpu *cpu) +{ + /* assert instr[30] == 0 + instr[28,21] == 11010110 + instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit + instr[29] = S : 0 ==> ok, 1 ==> UNALLOC + instr[15,10] = opcode : 000010 ==> UDIV, 000011 ==> CPUIV, + 001000 ==> LSLV, 001001 ==> LSRV + 001010 ==> ASRV, 001011 ==> RORV + ow ==> UNALLOC. */ + + uint32_t dispatch; + uint32_t S = uimm (aarch64_get_instr (cpu), 29, 29); + uint32_t opcode = uimm (aarch64_get_instr (cpu), 15, 10); + + if (S == 1) + HALT_UNALLOC; + + if (opcode & 0x34) + HALT_UNALLOC; + + dispatch = ( (uimm (aarch64_get_instr (cpu), 31, 31) << 3) + | (uimm (opcode, 3, 3) << 2) + | uimm (opcode, 1, 0)); + switch (dispatch) + { + case 2: udiv32 (cpu); return; + case 3: cpuiv32 (cpu); return; + case 4: lslv32 (cpu); return; + case 5: lsrv32 (cpu); return; + case 6: asrv32 (cpu); return; + case 7: rorv32 (cpu); return; + case 10: udiv64 (cpu); return; + case 11: cpuiv64 (cpu); return; + case 12: lslv64 (cpu); return; + case 13: lsrv64 (cpu); return; + case 14: asrv64 (cpu); return; + case 15: rorv64 (cpu); return; + default: HALT_UNALLOC; + } +} + + +/* Multiply. */ + +/* 32 bit multiply and add. */ +static void +madd32 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned ra = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_reg_u32 (cpu, ra, NO_SP) + + aarch64_get_reg_u32 (cpu, rn, NO_SP) + * aarch64_get_reg_u32 (cpu, rm, NO_SP)); +} + +/* 64 bit multiply and add. */ +static void +madd64 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned ra = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_reg_u64 (cpu, ra, NO_SP) + + aarch64_get_reg_u64 (cpu, rn, NO_SP) + * aarch64_get_reg_u64 (cpu, rm, NO_SP)); +} + +/* 32 bit multiply and sub. */ +static void +msub32 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned ra = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_reg_u32 (cpu, ra, NO_SP) + - aarch64_get_reg_u32 (cpu, rn, NO_SP) + * aarch64_get_reg_u32 (cpu, rm, NO_SP)); +} + +/* 64 bit multiply and sub. */ +static void +msub64 (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned ra = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + aarch64_get_reg_u64 (cpu, ra, NO_SP) + - aarch64_get_reg_u64 (cpu, rn, NO_SP) + * aarch64_get_reg_u64 (cpu, rm, NO_SP)); +} + +/* Signed multiply add long -- source, source2 : 32 bit, source3 : 64 bit. */ +static void +smaddl (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned ra = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + /* N.B. we need to multiply the signed 32 bit values in rn, rm to + obtain a 64 bit product. */ + aarch64_set_reg_s64 + (cpu, rd, NO_SP, + aarch64_get_reg_s64 (cpu, ra, NO_SP) + + ((int64_t) aarch64_get_reg_s32 (cpu, rn, NO_SP)) + * ((int64_t) aarch64_get_reg_s32 (cpu, rm, NO_SP))); +} + +/* Signed multiply sub long -- source, source2 : 32 bit, source3 : 64 bit. */ +static void +smsubl (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned ra = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + /* N.B. we need to multiply the signed 32 bit values in rn, rm to + obtain a 64 bit product. */ + aarch64_set_reg_s64 + (cpu, rd, NO_SP, + aarch64_get_reg_s64 (cpu, ra, NO_SP) + - ((int64_t) aarch64_get_reg_s32 (cpu, rn, NO_SP)) + * ((int64_t) aarch64_get_reg_s32 (cpu, rm, NO_SP))); +} + +/* Integer Multiply/Divide. */ + +/* First some macros and a helper function. */ +/* Macros to test or access elements of 64 bit words. */ + +/* Mask used to access lo 32 bits of 64 bit unsigned int. */ +#define LOW_WORD_MASK ((1ULL << 32) - 1) +/* Return the lo 32 bit word of a 64 bit unsigned int as a 64 bit unsigned int. */ +#define lowWordToU64(_value_u64) ((_value_u64) & LOW_WORD_MASK) +/* Return the hi 32 bit word of a 64 bit unsigned int as a 64 bit unsigned int. */ +#define highWordToU64(_value_u64) ((_value_u64) >> 32) + +/* Offset of sign bit in 64 bit signed integger. */ +#define SIGN_SHIFT_U64 63 +/* The sign bit itself -- also identifies the minimum negative int value. */ +#define SIGN_BIT_U64 (1UL << SIGN_SHIFT_U64) +/* Return true if a 64 bit signed int presented as an unsigned int is the + most negative value. */ +#define isMinimumU64(_value_u64) ((_value_u64) == SIGN_BIT_U64) +/* Return true (non-zero) if a 64 bit signed int presented as an unsigned + int has its sign bit set to false. */ +#define isSignSetU64(_value_u64) ((_value_u64) & SIGN_BIT_U64) +/* Return 1L or -1L according to whether a 64 bit signed int presented as + an unsigned int has its sign bit set or not. */ +#define signOfU64(_value_u64) (1L + (((value_u64) >> SIGN_SHIFT_U64) * -2L) +/* Clear the sign bit of a 64 bit signed int presented as an unsigned int. */ +#define clearSignU64(_value_u64) ((_value_u64) &= ~SIGN_BIT_U64) + +/* Multiply two 64 bit ints and return. + the hi 64 bits of the 128 bit product. */ + +static uint64_t +mul64hi (uint64_t value1, uint64_t value2) +{ + uint64_t resultmid1; + uint64_t result; + uint64_t value1_lo = lowWordToU64 (value1); + uint64_t value1_hi = highWordToU64 (value1) ; + uint64_t value2_lo = lowWordToU64 (value2); + uint64_t value2_hi = highWordToU64 (value2); + + /* Cross-multiply and collect results. */ + + uint64_t xproductlo = value1_lo * value2_lo; + uint64_t xproductmid1 = value1_lo * value2_hi; + uint64_t xproductmid2 = value1_hi * value2_lo; + uint64_t xproducthi = value1_hi * value2_hi; + uint64_t carry = 0; + /* Start accumulating 64 bit results. */ + /* Drop bottom half of lowest cross-product. */ + uint64_t resultmid = xproductlo >> 32; + /* Add in middle products. */ + resultmid = resultmid + xproductmid1; + + /* Check for overflow. */ + if (resultmid < xproductmid1) + /* Carry over 1 into top cross-product. */ + carry++; + + resultmid1 = resultmid + xproductmid2; + + /* Check for overflow. */ + if (resultmid1 < xproductmid2) + /* Carry over 1 into top cross-product. */ + carry++; + + /* Drop lowest 32 bits of middle cross-product. */ + result = resultmid1 >> 32; + + /* Add top cross-product plus and any carry. */ + result += xproducthi + carry; + + return result; +} + +/* Signed multiply high, source, source2 : + 64 bit, dest <-- high 64-bit of result. */ +static void +smulh (sim_cpu *cpu) +{ + uint64_t uresult; + int64_t result; + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + GReg ra = greg (aarch64_get_instr (cpu), 10); + int64_t value1 = aarch64_get_reg_u64 (cpu, rn, NO_SP); + int64_t value2 = aarch64_get_reg_u64 (cpu, rm, NO_SP); + uint64_t uvalue1; + uint64_t uvalue2; + int64_t signum = 1; + + if (ra != R31) + HALT_UNALLOC; + + /* Convert to unsigned and use the unsigned mul64hi routine + the fix the sign up afterwards. */ + if (value1 < 0) + { + signum *= -1L; + uvalue1 = -value1; + } + else + { + uvalue1 = value1; + } + + if (value2 < 0) + { + signum *= -1L; + uvalue2 = -value2; + } + else + { + uvalue2 = value2; + } + + uresult = mul64hi (uvalue1, uvalue2); + result = uresult; + result *= signum; + + aarch64_set_reg_s64 (cpu, rd, NO_SP, result); +} + +/* Unsigned multiply add long -- source, source2 : + 32 bit, source3 : 64 bit. */ +static void +umaddl (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned ra = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + /* N.B. we need to multiply the signed 32 bit values in rn, rm to + obtain a 64 bit product. */ + aarch64_set_reg_u64 + (cpu, rd, NO_SP, + aarch64_get_reg_u64 (cpu, ra, NO_SP) + + ((uint64_t) aarch64_get_reg_u32 (cpu, rn, NO_SP)) + * ((uint64_t) aarch64_get_reg_u32 (cpu, rm, NO_SP))); +} + +/* Unsigned multiply sub long -- source, source2 : 32 bit, source3 : 64 bit. */ +static void +umsubl (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned ra = uimm (aarch64_get_instr (cpu), 14, 10); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + + /* N.B. we need to multiply the signed 32 bit values in rn, rm to + obtain a 64 bit product. */ + aarch64_set_reg_u64 + (cpu, rd, NO_SP, + aarch64_get_reg_u64 (cpu, ra, NO_SP) + - ((uint64_t) aarch64_get_reg_u32 (cpu, rn, NO_SP)) + * ((uint64_t) aarch64_get_reg_u32 (cpu, rm, NO_SP))); +} + +/* Unsigned multiply high, source, source2 : + 64 bit, dest <-- high 64-bit of result. */ +static void +umulh (sim_cpu *cpu) +{ + unsigned rm = uimm (aarch64_get_instr (cpu), 20, 16); + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + unsigned rd = uimm (aarch64_get_instr (cpu), 4, 0); + GReg ra = greg (aarch64_get_instr (cpu), 10); + + if (ra != R31) + HALT_UNALLOC; + + aarch64_set_reg_u64 (cpu, rd, NO_SP, + mul64hi (aarch64_get_reg_u64 (cpu, rn, NO_SP), + aarch64_get_reg_u64 (cpu, rm, NO_SP))); +} + +static void +dexDataProc3Source (sim_cpu *cpu) +{ + /* assert instr[28,24] == 11011. */ + /* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit (for rd at least) + instr[30,29] = op54 : 00 ==> ok, ow ==> UNALLOC + instr[23,21] = op31 : 111 ==> UNALLOC, o2 ==> ok + instr[15] = o0 : 0/1 ==> ok + instr[23,21:15] ==> op : 0000 ==> MADD, 0001 ==> MSUB, (32/64 bit) + 0010 ==> SMADDL, 0011 ==> SMSUBL, (64 bit only) + 0100 ==> SMULH, (64 bit only) + 1010 ==> UMADDL, 1011 ==> UNSUBL, (64 bit only) + 1100 ==> UMULH (64 bit only) + ow ==> UNALLOC. */ + + uint32_t dispatch; + uint32_t size = uimm (aarch64_get_instr (cpu), 31, 31); + uint32_t op54 = uimm (aarch64_get_instr (cpu), 30, 29); + uint32_t op31 = uimm (aarch64_get_instr (cpu), 23, 21); + uint32_t o0 = uimm (aarch64_get_instr (cpu), 15, 15); + + if (op54 != 0) + HALT_UNALLOC; + + if (size == 0) + { + if (op31 != 0) + HALT_UNALLOC; + + if (o0 == 0) + madd32 (cpu); + else + msub32 (cpu); + return; + } + + dispatch = (op31 << 1) | o0; + + switch (dispatch) + { + case 0: madd64 (cpu); return; + case 1: msub64 (cpu); return; + case 2: smaddl (cpu); return; + case 3: smsubl (cpu); return; + case 4: smulh (cpu); return; + case 10: umaddl (cpu); return; + case 11: umsubl (cpu); return; + case 12: umulh (cpu); return; + default: HALT_UNALLOC; + } +} + +static void +dexDPReg (sim_cpu *cpu) +{ + /* uint32_t group = dispatchGroup (aarch64_get_instr (cpu)); + assert group == GROUP_DPREG_0101 || group == GROUP_DPREG_1101 + bits [28:24:21] of a DPReg are the secondary dispatch vector. */ + uint32_t group2 = dispatchDPReg (aarch64_get_instr (cpu)); + + switch (group2) + { + case DPREG_LOG_000: + case DPREG_LOG_001: + dexLogicalShiftedRegister (cpu); return; + + case DPREG_ADDSHF_010: + dexAddSubtractShiftedRegister (cpu); return; + + case DPREG_ADDEXT_011: + dexAddSubtractExtendedRegister (cpu); return; + + case DPREG_ADDCOND_100: + { + /* This set bundles a variety of different operations. */ + /* Check for. */ + /* 1) add/sub w carry. */ + uint32_t mask1 = 0x1FE00000U; + uint32_t val1 = 0x1A000000U; + /* 2) cond compare register/immediate. */ + uint32_t mask2 = 0x1FE00000U; + uint32_t val2 = 0x1A400000U; + /* 3) cond select. */ + uint32_t mask3 = 0x1FE00000U; + uint32_t val3 = 0x1A800000U; + /* 4) data proc 1/2 source. */ + uint32_t mask4 = 0x1FE00000U; + uint32_t val4 = 0x1AC00000U; + + if ((aarch64_get_instr (cpu) & mask1) == val1) + dexAddSubtractWithCarry (cpu); + + else if ((aarch64_get_instr (cpu) & mask2) == val2) + CondCompare (cpu); + + else if ((aarch64_get_instr (cpu) & mask3) == val3) + dexCondSelect (cpu); + + else if ((aarch64_get_instr (cpu) & mask4) == val4) + { + /* Bit 30 is clear for data proc 2 source + and set for data proc 1 source. */ + if (aarch64_get_instr (cpu) & (1U << 30)) + dexDataProc1Source (cpu); + else + dexDataProc2Source (cpu); + } + + else + /* Should not reach here. */ + HALT_NYI; + + return; + } + + case DPREG_3SRC_110: + dexDataProc3Source (cpu); return; + + case DPREG_UNALLOC_101: + HALT_UNALLOC; + + case DPREG_3SRC_111: + dexDataProc3Source (cpu); return; + + default: + /* Should never reach here. */ + HALT_NYI; + } +} + +/* Unconditional Branch immediate. + Offset is a PC-relative byte offset in the range +/- 128MiB. + The offset is assumed to be raw from the decode i.e. the + simulator is expected to scale them from word offsets to byte. */ + +/* Unconditional branch. */ +static void +buc (sim_cpu *cpu, int32_t offset) +{ + aarch64_set_next_PC_by_offset (cpu, offset); +} + +static unsigned stack_depth = 0; + +/* Unconditional branch and link -- writes return PC to LR. */ +static void +bl (sim_cpu *cpu, int32_t offset) +{ + aarch64_save_LR (cpu); + aarch64_set_next_PC_by_offset (cpu, offset); + + if (TRACE_BRANCH_P (cpu)) + { + ++ stack_depth; + TRACE_BRANCH (cpu, + " %*scall %" PRIx64 " [%s]" + " [args: %" PRIx64 " %" PRIx64 " %" PRIx64 "]", + stack_depth, " ", aarch64_get_next_PC (cpu), + aarch64_get_func (aarch64_get_next_PC (cpu)), + aarch64_get_reg_u64 (cpu, 0, NO_SP), + aarch64_get_reg_u64 (cpu, 1, NO_SP), + aarch64_get_reg_u64 (cpu, 2, NO_SP) + ); + } +} + +/* Unconditional Branch register. + Branch/return address is in source register. */ + +/* Unconditional branch. */ +static void +br (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + aarch64_set_next_PC (cpu, aarch64_get_reg_u64 (cpu, rn, NO_SP)); +} + +/* Unconditional branch and link -- writes return PC to LR. */ +static void +blr (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + + /* The pseudo code in the spec says we update LR before fetching. + the value from the rn. */ + aarch64_save_LR (cpu); + aarch64_set_next_PC (cpu, aarch64_get_reg_u64 (cpu, rn, NO_SP)); + + if (TRACE_BRANCH_P (cpu)) + { + ++ stack_depth; + TRACE_BRANCH (cpu, + " %*scall %" PRIx64 " [%s]" + " [args: %" PRIx64 " %" PRIx64 " %" PRIx64 "]", + stack_depth, " ", aarch64_get_next_PC (cpu), + aarch64_get_func (aarch64_get_next_PC (cpu)), + aarch64_get_reg_u64 (cpu, 0, NO_SP), + aarch64_get_reg_u64 (cpu, 1, NO_SP), + aarch64_get_reg_u64 (cpu, 2, NO_SP) + ); + } +} + +/* Return -- assembler will default source to LR this is functionally + equivalent to br but, presumably, unlike br it side effects the + branch predictor. */ +static void +ret (sim_cpu *cpu) +{ + unsigned rn = uimm (aarch64_get_instr (cpu), 9, 5); + aarch64_set_next_PC (cpu, aarch64_get_reg_u64 (cpu, rn, NO_SP)); + + if (TRACE_BRANCH_P (cpu)) + { + TRACE_BRANCH (cpu, + " %*sreturn [result: %" PRIx64 "]", + stack_depth, " ", aarch64_get_reg_u64 (cpu, 0, NO_SP)); + -- stack_depth; + } +} + +/* NOP -- we implement this and call it from the decode in case we + want to intercept it later. */ + +static void +nop (sim_cpu *cpu) +{ +} + +/* Data synchronization barrier. */ + +static void +dsb (sim_cpu *cpu) +{ +} + +/* Data memory barrier. */ + +static void +dmb (sim_cpu *cpu) +{ +} + +/* Instruction synchronization barrier. */ + +static void +isb (sim_cpu *cpu) +{ +} + +static void +dexBranchImmediate (sim_cpu *cpu) +{ + /* assert instr[30,26] == 00101 + instr[31] ==> 0 == B, 1 == BL + instr[25,0] == imm26 branch offset counted in words. */ + + uint32_t top = uimm (aarch64_get_instr (cpu), 31, 31); + /* We have a 26 byte signed word offset which we need to pass to the + execute routine as a signed byte offset. */ + int32_t offset = simm32 (aarch64_get_instr (cpu), 25, 0) << 2; + + if (top) + bl (cpu, offset); + else + buc (cpu, offset); +} + +/* Control Flow. */ + +/* Conditional branch + + Offset is a PC-relative byte offset in the range +/- 1MiB pos is + a bit position in the range 0 .. 63 + + cc is a CondCode enum value as pulled out of the decode + + N.B. any offset register (source) can only be Xn or Wn. */ + +static void +bcc (sim_cpu *cpu, int32_t offset, CondCode cc) +{ + /* the test returns TRUE if CC is met. */ + if (testConditionCode (cpu, cc)) + aarch64_set_next_PC_by_offset (cpu, offset); +} + +/* 32 bit branch on register non-zero. */ +static void +cbnz32 (sim_cpu *cpu, int32_t offset) +{ + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + if (aarch64_get_reg_u32 (cpu, rt, NO_SP) != 0) + aarch64_set_next_PC_by_offset (cpu, offset); +} + +/* 64 bit branch on register zero. */ +static void +cbnz (sim_cpu *cpu, int32_t offset) +{ + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + if (aarch64_get_reg_u64 (cpu, rt, NO_SP) != 0) + aarch64_set_next_PC_by_offset (cpu, offset); +} + +/* 32 bit branch on register non-zero. */ +static void +cbz32 (sim_cpu *cpu, int32_t offset) +{ + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + if (aarch64_get_reg_u32 (cpu, rt, NO_SP) == 0) + aarch64_set_next_PC_by_offset (cpu, offset); +} + +/* 64 bit branch on register zero. */ +static void +cbz (sim_cpu *cpu, int32_t offset) +{ + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + if (aarch64_get_reg_u64 (cpu, rt, NO_SP) == 0) + aarch64_set_next_PC_by_offset (cpu, offset); +} + +/* Branch on register bit test non-zero -- one size fits all. */ +static void +tbnz (sim_cpu *cpu, uint32_t pos, int32_t offset) +{ + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + if (aarch64_get_reg_u64 (cpu, rt, NO_SP) & (1 << pos)) + aarch64_set_next_PC_by_offset (cpu, offset); +} + +/* branch on register bit test zero -- one size fits all. */ +static void +tbz (sim_cpu *cpu, uint32_t pos, int32_t offset) +{ + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + + if (!(aarch64_get_reg_u64 (cpu, rt, NO_SP) & (1 << pos))) + aarch64_set_next_PC_by_offset (cpu, offset); +} + +static void +dexCompareBranchImmediate (sim_cpu *cpu) +{ + /* instr[30,25] = 01 1010 + instr[31] = size : 0 ==> 32, 1 ==> 64 + instr[24] = op : 0 ==> CBZ, 1 ==> CBNZ + instr[23,5] = simm19 branch offset counted in words + instr[4,0] = rt */ + + uint32_t size = uimm (aarch64_get_instr (cpu), 31, 31); + uint32_t op = uimm (aarch64_get_instr (cpu), 24, 24); + int32_t offset = simm32 (aarch64_get_instr (cpu), 23, 5) << 2; + + if (size == 0) + { + if (op == 0) + cbz32 (cpu, offset); + else + cbnz32 (cpu, offset); + } + else + { + if (op == 0) + cbz (cpu, offset); + else + cbnz (cpu, offset); + } +} + +static void +dexTestBranchImmediate (sim_cpu *cpu) +{ + /* instr[31] = b5 : bit 5 of test bit idx + instr[30,25] = 01 1011 + instr[24] = op : 0 ==> TBZ, 1 == TBNZ + instr[23,19] = b40 : bits 4 to 0 of test bit idx + instr[18,5] = simm14 : signed offset counted in words + instr[4,0] = uimm5 */ + + uint32_t pos = ((uimm (aarch64_get_instr (cpu), 31, 31) << 4) + | uimm (aarch64_get_instr (cpu), 23,19)); + int32_t offset = simm32 (aarch64_get_instr (cpu), 18, 5) << 2; + + NYI_assert (30, 25, 0x1b); + + if (uimm (aarch64_get_instr (cpu), 24, 24) == 0) + tbz (cpu, pos, offset); + else + tbnz (cpu, pos, offset); +} + +static void +dexCondBranchImmediate (sim_cpu *cpu) +{ + /* instr[31,25] = 010 1010 + instr[24] = op1; op => 00 ==> B.cond + instr[23,5] = simm19 : signed offset counted in words + instr[4] = op0 + instr[3,0] = cond */ + + int32_t offset; + CondCode cc; + uint32_t op = ((uimm (aarch64_get_instr (cpu), 24, 24) << 1) + | uimm (aarch64_get_instr (cpu), 4, 4)); + + NYI_assert (31, 25, 0x2a); + + if (op != 0) + HALT_UNALLOC; + + offset = simm32 (aarch64_get_instr (cpu), 23, 5) << 2; + cc = condcode (aarch64_get_instr (cpu), 0); + + bcc (cpu, offset, cc); +} + +static void +dexBranchRegister (sim_cpu *cpu) +{ + /* instr[31,25] = 110 1011 + instr[24,21] = op : 0 ==> BR, 1 => BLR, 2 => RET, 3 => ERET, 4 => DRPS + instr[20,16] = op2 : must be 11111 + instr[15,10] = op3 : must be 000000 + instr[4,0] = op2 : must be 11111. */ + + uint32_t op = uimm (aarch64_get_instr (cpu), 24, 21); + uint32_t op2 = uimm (aarch64_get_instr (cpu), 20, 16); + uint32_t op3 = uimm (aarch64_get_instr (cpu), 15, 10); + uint32_t op4 = uimm (aarch64_get_instr (cpu), 4, 0); + + NYI_assert (31, 25, 0x6b); + + if (op2 != 0x1F || op3 != 0 || op4 != 0) + HALT_UNALLOC; + + if (op == 0) + br (cpu); + + else if (op == 1) + blr (cpu); + + else if (op == 2) + ret (cpu); + + else + { + /* ERET and DRPS accept 0b11111 for rn = aarch64_get_instr (cpu)[4,0]. */ + /* anything else is unallocated. */ + uint32_t rn = greg (aarch64_get_instr (cpu), 0); + + if (rn != 0x1f) + HALT_UNALLOC; + + if (op == 4 || op == 5) + HALT_NYI; + + HALT_UNALLOC; + } +} + +/* FIXME: We should get the Angel SWI values from ../../libgloss/aarch64/svc.h + but this may not be available. So instead we define the values we need + here. */ +#define AngelSVC_Reason_Open 0x01 +#define AngelSVC_Reason_Close 0x02 +#define AngelSVC_Reason_Write 0x05 +#define AngelSVC_Reason_Read 0x06 +#define AngelSVC_Reason_IsTTY 0x09 +#define AngelSVC_Reason_Seek 0x0A +#define AngelSVC_Reason_FLen 0x0C +#define AngelSVC_Reason_Remove 0x0E +#define AngelSVC_Reason_Rename 0x0F +#define AngelSVC_Reason_Clock 0x10 +#define AngelSVC_Reason_Time 0x11 +#define AngelSVC_Reason_System 0x12 +#define AngelSVC_Reason_Errno 0x13 +#define AngelSVC_Reason_GetCmdLine 0x15 +#define AngelSVC_Reason_HeapInfo 0x16 +#define AngelSVC_Reason_ReportException 0x18 +#define AngelSVC_Reason_Elapsed 0x30 + + +static void +handle_halt (sim_cpu *cpu, uint32_t val) +{ + uint64_t result = 0; + + if (val != 0xf000) + { + TRACE_SYSCALL (cpu, " HLT [0x%x]", val); + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), + sim_stopped, SIM_SIGTRAP); + } + + /* We have encountered an Angel SVC call. See if we can process it. */ + switch (aarch64_get_reg_u32 (cpu, 0, NO_SP)) + { + case AngelSVC_Reason_HeapInfo: + { + /* Get the values. */ + uint64_t stack_top = aarch64_get_stack_start (cpu); + uint64_t heap_base = aarch64_get_heap_start (cpu); + + /* Get the pointer */ + uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK); + ptr = aarch64_get_mem_u64 (cpu, ptr); + + /* Fill in the memory block. */ + /* Start addr of heap. */ + aarch64_set_mem_u64 (cpu, ptr + 0, heap_base); + /* End addr of heap. */ + aarch64_set_mem_u64 (cpu, ptr + 8, stack_top); + /* Lowest stack addr. */ + aarch64_set_mem_u64 (cpu, ptr + 16, heap_base); + /* Initial stack addr. */ + aarch64_set_mem_u64 (cpu, ptr + 24, stack_top); + + TRACE_SYSCALL (cpu, " AngelSVC: Get Heap Info"); + } + break; + + case AngelSVC_Reason_Open: + { + /* Get the pointer */ + /* uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK);. */ + /* FIXME: For now we just assume that we will only be asked + to open the standard file descriptors. */ + static int fd = 0; + result = fd ++; + + TRACE_SYSCALL (cpu, " AngelSVC: Open file %d", fd - 1); + } + break; + + case AngelSVC_Reason_Close: + { + uint64_t fh = aarch64_get_reg_u64 (cpu, 1, SP_OK); + TRACE_SYSCALL (cpu, " AngelSVC: Close file %d", (int) fh); + result = 0; + } + break; + + case AngelSVC_Reason_Errno: + result = 0; + TRACE_SYSCALL (cpu, " AngelSVC: Get Errno"); + break; + + case AngelSVC_Reason_Clock: + result = +#ifdef CLOCKS_PER_SEC + (CLOCKS_PER_SEC >= 100) + ? (clock () / (CLOCKS_PER_SEC / 100)) + : ((clock () * 100) / CLOCKS_PER_SEC) +#else + /* Presume unix... clock() returns microseconds. */ + (clock () / 10000) +#endif + ; + TRACE_SYSCALL (cpu, " AngelSVC: Get Clock"); + break; + + case AngelSVC_Reason_GetCmdLine: + { + /* Get the pointer */ + uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK); + ptr = aarch64_get_mem_u64 (cpu, ptr); + + /* FIXME: No command line for now. */ + aarch64_set_mem_u64 (cpu, ptr, 0); + TRACE_SYSCALL (cpu, " AngelSVC: Get Command Line"); + } + break; + + case AngelSVC_Reason_IsTTY: + result = 1; + TRACE_SYSCALL (cpu, " AngelSVC: IsTTY ?"); + break; + + case AngelSVC_Reason_Write: + { + /* Get the pointer */ + uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK); + /* Get the write control block. */ + uint64_t fd = aarch64_get_mem_u64 (cpu, ptr); + uint64_t buf = aarch64_get_mem_u64 (cpu, ptr + 8); + uint64_t len = aarch64_get_mem_u64 (cpu, ptr + 16); + + TRACE_SYSCALL (cpu, "write of %" PRIx64 " bytes from %" + PRIx64 " on descriptor %" PRIx64, + len, buf, fd); + + if (len > 1280) + { + TRACE_SYSCALL (cpu, + " AngelSVC: Write: Suspiciously long write: %ld", + (long) len); + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), + sim_stopped, SIM_SIGBUS); + } + else if (fd == 1) + { + printf ("%.*s", (int) len, aarch64_get_mem_ptr (cpu, buf)); + if (disas) + /* So that the output stays in sync with trace output. */ + fflush (stdout); + } + else if (fd == 2) + { + TRACE (cpu, 0, "\n"); + sim_io_eprintf (CPU_STATE (cpu), "%.*s", + (int) len, aarch64_get_mem_ptr (cpu, buf)); + TRACE (cpu, 0, "\n"); + } + else + { + TRACE_SYSCALL (cpu, + " AngelSVC: Write: Unexpected file handle: %d", + (int) fd); + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), + sim_stopped, SIM_SIGABRT); + } + } + break; + + case AngelSVC_Reason_ReportException: + { + /* Get the pointer */ + uint64_t ptr = aarch64_get_reg_u64 (cpu, 1, SP_OK); + /*ptr = aarch64_get_mem_u64 (cpu, ptr);. */ + uint64_t type = aarch64_get_mem_u64 (cpu, ptr); + uint64_t state = aarch64_get_mem_u64 (cpu, ptr + 8); + + TRACE_SYSCALL (cpu, + "Angel Exception: type 0x%" PRIx64 " state %" PRIx64, + type, state); + + if (type == 0x20026) + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), + sim_exited, state); + else + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), + sim_stopped, SIM_SIGINT); + } + break; + + case AngelSVC_Reason_Read: + case AngelSVC_Reason_FLen: + case AngelSVC_Reason_Seek: + case AngelSVC_Reason_Remove: + case AngelSVC_Reason_Time: + case AngelSVC_Reason_System: + case AngelSVC_Reason_Rename: + case AngelSVC_Reason_Elapsed: + default: + TRACE_SYSCALL (cpu, " HLT [Unknown angel %x]", + aarch64_get_reg_u32 (cpu, 0, NO_SP)); + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), + sim_stopped, SIM_SIGTRAP); + } + + aarch64_set_reg_u64 (cpu, 0, NO_SP, result); +} + +static void +dexExcpnGen (sim_cpu *cpu) +{ + /* instr[31:24] = 11010100 + instr[23,21] = opc : 000 ==> GEN EXCPN, 001 ==> BRK + 010 ==> HLT, 101 ==> DBG GEN EXCPN + instr[20,5] = imm16 + instr[4,2] = opc2 000 ==> OK, ow ==> UNALLOC + instr[1,0] = LL : discriminates opc */ + + uint32_t opc = uimm (aarch64_get_instr (cpu), 23, 21); + uint32_t imm16 = uimm (aarch64_get_instr (cpu), 20, 5); + uint32_t opc2 = uimm (aarch64_get_instr (cpu), 4, 2); + uint32_t LL; + + NYI_assert (31, 24, 0xd4); + + if (opc2 != 0) + HALT_UNALLOC; + + LL = uimm (aarch64_get_instr (cpu), 1, 0); + + /* We only implement HLT and BRK for now. */ + if (opc == 1 && LL == 0) + { + TRACE_EVENTS (cpu, " BRK [0x%x]", imm16); + sim_engine_halt (CPU_STATE (cpu), cpu, NULL, aarch64_get_PC (cpu), + sim_exited, aarch64_get_reg_s32 (cpu, R0, SP_OK)); + } + + if (opc == 2 && LL == 0) + handle_halt (cpu, imm16); + + else if (opc == 0 || opc == 5) + HALT_NYI; + + else + HALT_UNALLOC; +} + +static void +dexSystem (sim_cpu *cpu) +{ + /* instr[31:22] = 1101 01010 0 + instr[21] = L + instr[20,19] = op0 + instr[18,16] = op1 + instr[15,12] = CRn + instr[11,8] = CRm + instr[7,5] = op2 + instr[4,0] = uimm5 */ + + /* We are interested in HINT, DSB, DMB and ISB + + Hint #0 encodes NOOP (this is the only hint we care about) + L == 0, op0 == 0, op1 = 011, CRn = 0010, Rt = 11111, + CRm op2 != 0000 000 OR CRm op2 == 0000 000 || CRm op > 0000 101 + + DSB, DMB, ISB are data store barrier, data memory barrier and + instruction store barrier, respectively, where + + L == 0, op0 == 0, op1 = 011, CRn = 0011, Rt = 11111, + op2 : DSB ==> 100, DMB ==> 101, ISB ==> 110 + CRm<3:2> ==> domain, CRm<1:0> ==> types, + domain : 00 ==> OuterShareable, 01 ==> Nonshareable, + 10 ==> InerShareable, 11 ==> FullSystem + types : 01 ==> Reads, 10 ==> Writes, + 11 ==> All, 00 ==> All (domain == FullSystem). */ + + unsigned rt = uimm (aarch64_get_instr (cpu), 4, 0); + uint32_t l_op0_op1_crn = uimm (aarch64_get_instr (cpu), 21, 12); + + NYI_assert (31, 22, 0x354); + + switch (l_op0_op1_crn) + { + case 0x032: + if (rt == 0x1F) + { + /* NOP has CRm != 0000 OR. */ + /* (CRm == 0000 AND (op2 == 000 OR op2 > 101)). */ + uint32_t crm = uimm (aarch64_get_instr (cpu), 11, 8); + uint32_t op2 = uimm (aarch64_get_instr (cpu), 7, 5); + + if (crm != 0 || (op2 == 0 || op2 > 5)) + { + /* Actually call nop method so we can reimplement it later. */ + nop (cpu); + return; + } + } + HALT_NYI; + + case 0x033: + { + uint32_t op2 = uimm (aarch64_get_instr (cpu), 7, 5); + + switch (op2) + { + case 2: + HALT_NYI; + + case 4: dsb (cpu); return; + case 5: dmb (cpu); return; + case 6: isb (cpu); return; + case 7: + default: HALT_UNALLOC; + } + } + + case 0x3B0: + /* MRS Wt, sys-reg. */ + /* FIXME: Ignore for now. */ + return; + + case 0x3B4: + case 0x3BD: + /* MRS Xt, sys-reg. */ + /* FIXME: Ignore for now. */ + return; + + case 0x0B7: + /* DC <type>, x<n>. */ + /* FIXME: Ignore for now. */ + return; + + default: + if (uimm (aarch64_get_instr (cpu), 21, 20) == 0x1) + /* MSR <sys-reg>, <Xreg>. */ + return; + HALT_NYI; + } +} + +static void +dexBr (sim_cpu *cpu) +{ + /* uint32_t group = dispatchGroup (aarch64_get_instr (cpu)); + assert group == GROUP_BREXSYS_1010 || group == GROUP_BREXSYS_1011 + bits [31,29] of a BrExSys are the secondary dispatch vector. */ + uint32_t group2 = dispatchBrExSys (aarch64_get_instr (cpu)); + + switch (group2) + { + case BR_IMM_000: + return dexBranchImmediate (cpu); + + case BR_IMMCMP_001: + /* Compare has bit 25 clear while test has it set. */ + if (!uimm (aarch64_get_instr (cpu), 25, 25)) + dexCompareBranchImmediate (cpu); + else + dexTestBranchImmediate (cpu); + return; + + case BR_IMMCOND_010: + /* This is a conditional branch if bit 25 is clear otherwise + unallocated. */ + if (!uimm (aarch64_get_instr (cpu), 25, 25)) + dexCondBranchImmediate (cpu); + else + HALT_UNALLOC; + return; + + case BR_UNALLOC_011: + HALT_UNALLOC; + + case BR_IMM_100: + dexBranchImmediate (cpu); + return; + + case BR_IMMCMP_101: + /* Compare has bit 25 clear while test has it set. */ + if (!uimm (aarch64_get_instr (cpu), 25, 25)) + dexCompareBranchImmediate (cpu); + else + dexTestBranchImmediate (cpu); + return; + + case BR_REG_110: + /* Unconditional branch reg has bit 25 set. */ + if (uimm (aarch64_get_instr (cpu), 25, 25)) + dexBranchRegister (cpu); + + /* This includes both Excpn Gen, System and unalloc operations. + We need to decode the Excpn Gen operation BRK so we can plant + debugger entry points. + Excpn Gen operations have aarch64_get_instr (cpu)[24] = 0. + we need to decode at least one of the System operations NOP + which is an alias for HINT #0. + System operations have aarch64_get_instr (cpu)[24,22] = 100. */ + else if (uimm (aarch64_get_instr (cpu), 24, 24) == 0) + dexExcpnGen (cpu); + + else if (uimm (aarch64_get_instr (cpu), 24, 22) == 4) + dexSystem (cpu); + + else + HALT_UNALLOC; + + return; + + case BR_UNALLOC_111: + HALT_UNALLOC; + + default: + /* Should never reach here. */ + HALT_NYI; + } +} + +static void +aarch64_decode_and_execute (sim_cpu *cpu, uint64_t pc) +{ + /* We need to check if gdb wants an in here. */ + /* checkBreak (cpu);. */ + + uint64_t group = dispatchGroup (aarch64_get_instr (cpu)); + + switch (group) + { + case GROUP_PSEUDO_0000: dexPseudo (cpu); break; + case GROUP_LDST_0100: dexLdSt (cpu); break; + case GROUP_DPREG_0101: dexDPReg (cpu); break; + case GROUP_LDST_0110: dexLdSt (cpu); break; + case GROUP_ADVSIMD_0111: dexAdvSIMD0 (cpu); break; + case GROUP_DPIMM_1000: dexDPImm (cpu); break; + case GROUP_DPIMM_1001: dexDPImm (cpu); break; + case GROUP_BREXSYS_1010: dexBr (cpu); break; + case GROUP_BREXSYS_1011: dexBr (cpu); break; + case GROUP_LDST_1100: dexLdSt (cpu); break; + case GROUP_DPREG_1101: dexDPReg (cpu); break; + case GROUP_LDST_1110: dexLdSt (cpu); break; + case GROUP_ADVSIMD_1111: dexAdvSIMD1 (cpu); break; + + case GROUP_UNALLOC_0001: + case GROUP_UNALLOC_0010: + case GROUP_UNALLOC_0011: + HALT_UNALLOC; + + default: + /* Should never reach here. */ + HALT_NYI; + } +} + +static bfd_boolean +aarch64_step (sim_cpu *cpu) +{ + uint64_t pc = aarch64_get_PC (cpu); + + if (pc == TOP_LEVEL_RETURN_PC) + return FALSE; + + aarch64_set_next_PC (cpu, pc + 4); + aarch64_get_instr (cpu) = aarch64_get_mem_u32 (cpu, pc); + + if (TRACE_INSN_P (cpu)) + { + if (disas) + TRACE_INSN (cpu, " pc = %" PRIx64 " ", pc); + else + TRACE_INSN (cpu, " pc = %" PRIx64 " instr = %x", pc, + aarch64_get_instr (cpu)); + } + else if (disas) + sim_io_eprintf (CPU_STATE (cpu), " %" PRIx64 " ", pc); + + if (disas) + aarch64_print_insn (CPU_STATE (cpu), pc); + + aarch64_decode_and_execute (cpu, pc); + + return TRUE; +} + +void +aarch64_run (SIM_DESC sd) +{ + sim_cpu *cpu = STATE_CPU (sd, 0); + + while (aarch64_step (cpu)) + aarch64_update_PC (cpu); + + sim_engine_halt (sd, NULL, NULL, aarch64_get_PC (cpu), + sim_exited, aarch64_get_reg_s32 (cpu, R0, SP_OK)); +} + +void +aarch64_init (sim_cpu *cpu, uint64_t pc) +{ + uint64_t sp = aarch64_get_stack_start (cpu); + + /* Install SP, FP and PC and set LR to -20 + so we can detect a top-level return. */ + aarch64_set_reg_u64 (cpu, SP, SP_OK, sp); + aarch64_set_reg_u64 (cpu, FP, SP_OK, sp); + aarch64_set_reg_u64 (cpu, LR, SP_OK, TOP_LEVEL_RETURN_PC); + aarch64_set_next_PC (cpu, pc); + aarch64_update_PC (cpu); + aarch64_init_LIT_table (); +} diff --git a/sim/aarch64/simulator.h b/sim/aarch64/simulator.h new file mode 100644 index 0000000..1f22448 --- /dev/null +++ b/sim/aarch64/simulator.h @@ -0,0 +1,57 @@ +/* simulator.h -- Prototypes for AArch64 simulator functions. + + Copyright (C) 2015 Free Software Foundation, Inc. + + Contributed by Red Hat. + + This file is part of GDB. + + 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; either version 3 of the License, or + (at your option) any later version. + + 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _SIMULATOR_H +#define _SIMULATOR_H + +#include "config.h" +#include <sys/types.h> +#include <setjmp.h> + +#include "sim-main.h" +#include "decode.h" + +extern bfd_boolean disas; + +#define TOP_LEVEL_RETURN_PC 0xffffffffffffffecULL + +/* Call this to set the start stack pointer, frame pointer and pc + before calling run or step. Also sets link register to a special + value (-20) so we can detect a top level return. This function + should be called from the sim setup routine running on the alt + stack, and should pass in the current top of C stack for SP and + the FP of the caller for fp. PC should be sthe start of the + AARCH64 code segment to be executed. */ + +extern void aarch64_init (sim_cpu *, uint64_t); + +/* Call this to run from the current PC without stopping until we + either return from the top frame, execute a halt or break or we + hit an error. */ + +extern void aarch64_run (SIM_DESC); + +extern const char * aarch64_get_func (uint64_t); +extern void aarch64_print_insn (SIM_DESC, uint64_t); +extern uint64_t aarch64_get_sym_value (const char *); +extern void aarch64_init_LIT_table (void); + +#endif /* _SIMULATOR_H */ |