OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/gnu-stable/gdb-7.2/sim/igen
    from Rev 835 to Rev 841
    Reverse comparison

Rev 835 → Rev 841

/ld-cache.c
0,0 → 1,116
/* The IGEN simulator generator for GDB, the GNU Debugger.
 
Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
Contributed by Andrew Cagney.
 
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 "misc.h"
#include "lf.h"
#include "table.h"
#include "filter.h"
#include "igen.h"
 
#include "ld-insn.h"
#include "ld-cache.h"
 
#ifndef NULL
#define NULL 0
#endif
 
 
enum
{
ca_type,
ca_field_name,
ca_derived_name,
ca_type_def,
ca_expression,
nr_cache_rule_fields,
};
 
static const name_map cache_type_map[] = {
{"cache", cache_value},
{"compute", compute_value},
{"scratch", scratch_value},
{NULL, 0},
};
 
 
cache_entry *
load_cache_table (char *file_name)
{
cache_entry *cache = NULL;
cache_entry **last = &cache;
table *file = table_open (file_name);
table_entry *entry;
while ((entry = table_read (file)) != NULL)
{
cache_entry *new_rule = ZALLOC (cache_entry);
new_rule->line = entry->line;
new_rule->entry_type = name2i (entry->field[ca_type], cache_type_map);
new_rule->name = entry->field[ca_derived_name];
filter_parse (&new_rule->original_fields, entry->field[ca_field_name]);
new_rule->type = entry->field[ca_type_def];
/* expression is the concatenation of the remaining fields */
if (entry->nr_fields > ca_expression)
{
int len = 0;
int chi;
for (chi = ca_expression; chi < entry->nr_fields; chi++)
{
len += strlen (" : ") + strlen (entry->field[chi]);
}
new_rule->expression = NZALLOC (char, len);
strcpy (new_rule->expression, entry->field[ca_expression]);
for (chi = ca_expression + 1; chi < entry->nr_fields; chi++)
{
strcat (new_rule->expression, " : ");
strcat (new_rule->expression, entry->field[chi]);
}
}
/* insert it */
*last = new_rule;
last = &new_rule->next;
}
return cache;
}
 
 
 
#ifdef MAIN
 
igen_options options;
 
int
main (int argc, char **argv)
{
cache_entry *rules = NULL;
lf *l;
 
if (argc != 2)
error (NULL, "Usage: cache <cache-file>\n");
 
rules = load_cache_table (argv[1]);
l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
dump_cache_entries (l, "(", rules, ")\n");
 
return 0;
}
#endif
ld-cache.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: configure =================================================================== --- configure (nonexistent) +++ configure (revision 841) @@ -0,0 +1,5111 @@ +#! /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" + 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'" + + +exec 7<&0 &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="table.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +RANLIB +AR +LIBIBERTY_LIB +RANLIB_FOR_BUILD +CFLAGS_FOR_BUILD +CC_FOR_BUILD +AR_FLAGS_FOR_BUILD +AR_FOR_BUILD +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 +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +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 +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' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +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-build-warnings Enable build-time compiler warnings if gcc is used + --enable-gdb-build-warnings Enable SIM specific build-time compiler warnings if gcc is used + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + 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 +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 + + + + + + +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. + + +# 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' + +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 +#include +#include +#include +/* 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 + + + + +# NOTE: Don't add -Wall or -Wunused, they both include +# -Wunused-parameter which reports bogus warnings. +# NOTE: If you add to this list, remember to update +# gdb/doc/gdbint.texinfo. +build_warnings="-Wimplicit -Wreturn-type -Wcomment -Wtrigraphs \ +-Wformat -Wparentheses -Wpointer-arith" +# GCC supports -Wuninitialized only with -O or -On, n != 0. +if test x${CFLAGS+set} = xset; then + case "${CFLAGS}" in + *"-O0"* ) ;; + *"-O"* ) + build_warnings="${build_warnings} -Wuninitialized" + ;; + esac +else + build_warnings="${build_warnings} -Wuninitialized" +fi +# Up for debate: -Wswitch -Wcomment -trigraphs -Wtrigraphs +# -Wunused-function -Wunused-label -Wunused-variable -Wunused-value +# -Wchar-subscripts -Wtraditional -Wshadow -Wcast-qual +# -Wcast-align -Wwrite-strings -Wconversion -Wstrict-prototypes +# -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls +# -Woverloaded-virtual -Winline -Werror" +# 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="" +WERROR_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 + + +# Put a plausible default for CC_FOR_BUILD in Makefile. +if test "x$cross_compiling" = "xno" -a "x$host" != "xi386-windows"; then + AR_FOR_BUILD='$(AR)' + AR_FLAGS_FOR_BUILD='$(AR_FLAGS)' + CC_FOR_BUILD='$(CC)' + CFLAGS_FOR_BUILD='$(CFLAGS)' + RANLIB_FOR_BUILD='$(RANLIB)' + LIBIBERTY_LIB=../../libiberty/libiberty.a +else + AR_FOR_BUILD=${AR_FOR_BUILD-ar} + AR_FLAGS_FOR_BUILD=${AR_FLAGS_FOR_BUILD-rc} + CC_FOR_BUILD=${CC_FOR_BUILD-gcc} + CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-"-g"} + RANLIB_FOR_BUILD=${RANLIB_FOR_BUILD-ranlib} + LIBIBERTY_LIB= +fi + + +# 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}- + +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"` + + +. ${srcdir}/../../bfd/configure.host + +ac_config_headers="$ac_config_headers config.h:config.in" + + +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 to if __STDC__ is defined, since + # 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 +#else +# include +#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 +_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 to if __STDC__ is defined, since + # 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 +#else +# include +#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 +_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 +#include +#include +#include + +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 + +_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 + +_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 +#include +#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 + + +for ac_header in stdlib.h string.h strings.h sys/stat.h sys/types.h unistd.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 + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 +$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_ac_Header=yes" +else + eval "$as_ac_Header=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$as_ac_Header + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if test "${ac_cv_search_opendir+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 opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; 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_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then : + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if test "${ac_cv_search_opendir+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 opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; 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_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then : + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + + + + + + + + + + + +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 + + +ac_config_files="$ac_config_files Makefile" + +ac_config_commands="$ac_config_commands default" + +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 + + + +: ${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_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 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' +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 +_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" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; + + *) 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_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` +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 +' >$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 +' >$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 :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 + ;; + + :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 + "default":C) case x$CONFIG_HEADERS in xconfig.h:config.in) echo > stamp-h ;; esac ;; + + 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 +
configure Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: misc.h =================================================================== --- misc.h (nonexistent) +++ misc.h (revision 841) @@ -0,0 +1,142 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + + +/* Frustrating header junk */ + +#include "config.h" + + +enum +{ + default_insn_bit_size = 32, + max_insn_bit_size = 64, +}; + + +/* Define a 64bit data type */ + +#if defined __GNUC__ || defined _WIN32 +#ifdef __GNUC__ + +typedef long long signed64; +typedef unsigned long long unsigned64; + +#else /* _WIN32 */ + +typedef __int64 signed64; +typedef unsigned __int64 unsigned64; + +#endif /* _WIN32 */ +#else /* Not GNUC or WIN32 */ +/* Not supported */ +#endif + + +#include +#include + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#if !defined (__attribute__) && (!defined(__GNUC__) || __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)) +#define __attribute__(arg) +#endif + + + +#include "filter_host.h" + +typedef struct _line_ref line_ref; +struct _line_ref +{ + const char *file_name; + int line_nr; +}; + +/* Error appends a new line, warning and notify do not */ +typedef void error_func (const line_ref *line, char *msg, ...); + +extern error_func error; +extern error_func warning; +extern error_func notify; + + +#define ERROR(EXPRESSION) \ +do { \ + line_ref line; \ + line.file_name = filter_filename (__FILE__); \ + line.line_nr = __LINE__; \ + error (&line, EXPRESSION); \ +} while (0) + +#define ASSERT(EXPRESSION) \ +do { \ + if (!(EXPRESSION)) { \ + line_ref line; \ + line.file_name = filter_filename (__FILE__); \ + line.line_nr = __LINE__; \ + error(&line, "assertion failed - %s\n", #EXPRESSION); \ + } \ +} while (0) + +#define ZALLOC(TYPE) ((TYPE*) zalloc (sizeof(TYPE))) +#define NZALLOC(TYPE,N) ((TYPE*) zalloc (sizeof(TYPE) * (N))) +#if 0 +#define STRDUP(STRING) (strcpy (zalloc (strlen (STRING) + 1), (STRING))) +#define STRNDUP(STRING,LEN) (strncpy (zalloc ((LEN) + 1), (STRING), (LEN))) +#endif + +extern void *zalloc (long size); + +extern unsigned target_a2i (int ms_bit_nr, const char *a); + +extern unsigned i2target (int ms_bit_nr, unsigned bit); + +extern unsigned long long a2i (const char *a); + + +/* Try looking for name in the map table (returning the corresponding + integer value). + + If the the sentinal (NAME == NULL) its value if >= zero is returned + as the default. */ + +typedef struct _name_map +{ + const char *name; + int i; +} +name_map; + +extern int name2i (const char *name, const name_map * map); + +extern const char *i2name (const int i, const name_map * map);
misc.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: Makefile.in =================================================================== --- Makefile.in (nonexistent) +++ Makefile.in (revision 841) @@ -0,0 +1,186 @@ +# The IGEN simulator generator for GDB, the GNU Debugger. +# +# Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# +# Contributed by Andrew Cagney. +# +# 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 . + +default: all + +VPATH = @srcdir@ +srcdir = @srcdir@ +srcroot = $(srcdir)/../.. + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +host_alias = @host_alias@ +target_alias = @target_alias@ +program_transform_name = @program_transform_name@ +bindir = @bindir@ +libdir = @libdir@ +tooldir = $(libdir)/$(target_alias) + +datarootdir = @datarootdir@ +datadir = @datadir@ +mandir = @mandir@ +man1dir = $(mandir)/man1 +man2dir = $(mandir)/man2 +man3dir = $(mandir)/man3 +man4dir = $(mandir)/man4 +man5dir = $(mandir)/man5 +man6dir = $(mandir)/man6 +man7dir = $(mandir)/man7 +man8dir = $(mandir)/man8 +man9dir = $(mandir)/man9 +infodir = @infodir@ +includedir = @includedir@ + +SHELL = @SHELL@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +AR = @AR@ +CC = @CC@ +CFLAGS = @CFLAGS@ +RANLIB = @RANLIB@ + +AR_FOR_BUILD = @AR_FOR_BUILD@ +AR_FLAGS_FOR_BUILD = @AR_FLAGS_FOR_BUILD@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +RANLIB_FOR_BUILD = @RANLIB_FOR_BUILD@ + +WARN_CFLAGS = @WARN_CFLAGS@ +WERROR_CFLAGS = @WERROR_CFLAGS@ +IGEN_WARN_CFLAGS = $(WARN_CFLAGS) +IGEN_WERROR_CFLAGS = $(WERROR_CFLAGS) + +BISON = bison +MAKEINFO = makeinfo + +.NOEXPORT: +MAKEOVERRIDES= + +LIB_INCLUDES = -I$(srcdir)/../../include +INCLUDES = -I. -I$(srcdir) $(LIB_INCLUDES) + +LIBIBERTY_LIB = @LIBIBERTY_LIB@ + +BUILD_CFLAGS = \ + $(CFLAGS_FOR_BUILD) \ + $(IGEN_WARN_CFLAGS) \ + $(IGEN_WERROR_CFLAGS) \ + $(INCLUDES) +BUILD_LDFLAGS = + +all: igen +#all: tmp-filter tmp-table tmp-ld-insn tmp-ld-cache tmp-ld-decode tmp-gen + +.c.o: + $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $< + + +filter_filename.o: filter_filename.c filter_filename.h config.h ppc-config.h + +IGEN_OBJS=\ + table.o \ + lf.o misc.o \ + filter_host.o \ + ld-decode.o \ + ld-cache.o \ + filter.o \ + ld-insn.o \ + gen-model.o \ + gen-itable.o \ + gen-icache.o \ + gen-semantics.o \ + gen-idecode.o \ + gen-support.o \ + gen-engine.o \ + gen.o + +igen: igen.o $(IGEN_OBJS) + $(CC_FOR_BUILD) $(BUILD_LDFLAGS) -o igen igen.o $(IGEN_OBJS) $(LIBIBERTY_LIB) + +igen.o: igen.c misc.h filter_host.h lf.h table.h ld-decode.h ld-cache.h ld-insn.h filter.h gen-model.h gen-itable.h gen-icache.h gen-idecode.h gen-engine.h gen-semantics.h gen-support.h gen.h igen.h + $(CC_FOR_BUILD) $(BUILD_CFLAGS) -c $(srcdir)/igen.c + +tmp-table: table.c table.h misc.o lf.o filter_host.o + $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o tmp-table -DMAIN $(srcdir)/table.c misc.o lf.o filter_host.o $(BUILD_LIBS) + +tmp-filter: filter.c filter.h lf.o misc.o filter_host.o + $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o tmp-filter -DMAIN $(srcdir)/filter.c lf.o misc.o filter_host.o $(BUILD_LIBS) + +tmp-ld-decode: ld-decode.h ld-decode.c filter.o misc.o lf.o table.o filter_host.o gen.h igen.h + $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o tmp-ld-decode -DMAIN $(srcdir)/ld-decode.c filter.o misc.o lf.o table.o filter_host.o $(BUILD_LIBS) + +tmp-ld-cache: ld-cache.c ld-cache.h ld-insn.o misc.o lf.o table.o filter_host.o gen.h igen.h + $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o tmp-ld-cache -DMAIN $(srcdir)/ld-cache.c ld-insn.o filter.o misc.o lf.o table.o filter_host.o $(BUILD_LIBS) + +tmp-ld-insn: ld-insn.c ld-insn.h misc.o lf.o table.o filter_host.o filter.o gen.h igen.h + $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o tmp-ld-insn -DMAIN $(srcdir)/ld-insn.c misc.o lf.o table.o filter_host.o filter.o $(BUILD_LIBS) + +tmp-gen: gen.c gen.h ld-insn.o ld-decode.o misc.o lf.o table.o filter_host.o filter.o gen.h igen.h + $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o tmp-gen -DMAIN $(srcdir)/gen.c misc.o ld-insn.o ld-decode.o lf.o table.o filter_host.o filter.o $(BUILD_LIBS) + +filter_host.o: filter_host.c filter_host.h +table.o: table.c misc.h filter_host.h lf.h table.h +lf.o: lf.c misc.h filter_host.h lf.h +filter.o: filter.c misc.h lf.h table.h filter.h +ld-decode.o: ld-decode.c misc.h lf.h table.h ld-decode.h igen.h +ld-cache.o: ld-cache.c misc.h lf.h table.h ld-cache.h igen.h +ld-insn.o: ld-insn.c misc.h lf.h table.h ld-insn.h gen.h igen.h +gen-model.o: gen-model.c misc.h lf.h table.h gen-model.h ld-decode.h gen.h igen.h ld-insn.h +gen-itable.o: gen-itable.c misc.h lf.h table.h gen-itable.h ld-decode.h gen.h igen.h ld-insn.h gen.h filter.h +gen-icache.o: gen-icache.c misc.h lf.h table.h gen-icache.h ld-decode.h gen.h igen.h ld-insn.h gen-semantics.h gen-idecode.h filter.h +gen-semantics.o: gen-semantics.c misc.h lf.h table.h gen-semantics.h ld-decode.h gen.h igen.h ld-insn.h filter.h +gen-idecode.o: gen-idecode.c misc.h lf.h table.h gen-idecode.h gen-icache.h gen-semantics.h ld-decode.h gen.h igen.h ld-insn.h filter.h +gen-engine.o: gen-engine.c misc.h lf.h table.h gen-idecode.h gen-engine.h gen-icache.h gen-semantics.h ld-decode.h gen.h igen.h ld-insn.h filter.h +gen-support.o: gen-support.c misc.h lf.h table.h gen-support.h ld-decode.h gen.h igen.h ld-insn.h filter.h +gen.o: gen.c misc.h lf.h table.h gen-icache.h ld-decode.h gen.h igen.h ld-insn.h gen-semantics.h gen-idecode.h filter.h +misc.o: misc.c misc.h filter_host.h + + +tags etags: TAGS + +TAGS: + etags $(srcdir)/*.h $(srcdir)/*.c + +clean mostlyclean: + rm -f tmp-* *.[oasi] core igen + +distclean realclean: clean + rm -f TAGS Makefile config.cache config.status config.h defines.h stamp-h config.log + +maintainer-clean: distclean + rm -f *~ *.log ppc-config.h core *.core + +Makefile: Makefile.in config.status + CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status + +config.h: stamp-h ; @true +stamp-h: config.in config.status + CONFIG_FILES= CONFIG_HEADERS=config.h:config.in $(SHELL) ./config.status + +config.status: configure + $(SHELL) ./config.status --recheck + +install: +# Index: ld-insn.c =================================================================== --- ld-insn.c (nonexistent) +++ ld-insn.c (revision 841) @@ -0,0 +1,1797 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +#include "misc.h" +#include "lf.h" +#include "table.h" +#include "filter.h" +#include "igen.h" +#include "ld-insn.h" + +static insn_word_entry * +parse_insn_word (line_ref *line, char *string, int word_nr) +{ + char *chp; + insn_word_entry *word = ZALLOC (insn_word_entry); + + /* create a leading sentinal */ + word->first = ZALLOC (insn_field_entry); + word->first->first = -1; + word->first->last = -1; + word->first->width = 0; + + /* and a trailing sentinal */ + word->last = ZALLOC (insn_field_entry); + word->last->first = options.insn_bit_size; + word->last->last = options.insn_bit_size; + word->last->width = 0; + + /* link them together */ + word->first->next = word->last; + word->last->prev = word->first; + + /* now work through the formats */ + chp = skip_spaces (string); + + while (*chp != '\0') + { + char *start_pos; + int strlen_pos; + char *start_val; + int strlen_val; + insn_field_entry *new_field; + + /* create / link in the new field */ + new_field = ZALLOC (insn_field_entry); + new_field->next = word->last; + new_field->prev = word->last->prev; + new_field->next->prev = new_field; + new_field->prev->next = new_field; + new_field->word_nr = word_nr; + + /* break out the first field (if present) */ + start_pos = chp; + chp = skip_to_separator (chp, ".,!"); + strlen_pos = back_spaces (start_pos, chp) - start_pos; + + /* break out the second field (if present) */ + if (*chp != '.') + { + /* assume what was specified was the value (and not the start + position). Assume the value length implicitly specifies + the number of bits */ + start_val = start_pos; + strlen_val = strlen_pos; + start_pos = ""; + strlen_pos = 0; + } + else + { + chp++; /* skip `.' */ + chp = skip_spaces (chp); + start_val = chp; + if (*chp == '/' || *chp == '*') + { + do + { + chp++; + } + while (*chp == '/' || *chp == '*'); + } + else if (isalpha (*start_val)) + { + do + { + chp++; + } + while (isalnum (*chp) || *chp == '_'); + } + else if (isdigit (*start_val)) + { + do + { + chp++; + } + while (isalnum (*chp)); + } + strlen_val = chp - start_val; + chp = skip_spaces (chp); + } + if (strlen_val == 0) + error (line, "Empty value field\n"); + + /* break out any conditional fields - { [ "!" | "=" [ | } */ + while (*chp == '!' || *chp == '=') + { + char *start; + char *end; + int len; + insn_field_cond *new_cond = ZALLOC (insn_field_cond); + + /* determine the conditional test */ + switch (*chp) + { + case '=': + new_cond->test = insn_field_cond_eq; + break; + case '!': + new_cond->test = insn_field_cond_ne; + break; + default: + ASSERT (0); + } + + /* save the value */ + chp++; + chp = skip_spaces (chp); + start = chp; + chp = skip_to_separator (chp, "+,:!="); + end = back_spaces (start, chp); + len = end - start; + if (len == 0) + error (line, "Missing or invalid conditional value\n"); + new_cond->string = NZALLOC (char, len + 1); + strncpy (new_cond->string, start, len); + + /* determine the conditional type */ + if (isdigit (*start)) + { + /* [ "!" | "=" ] */ + new_cond->type = insn_field_cond_value; + new_cond->value = a2i (new_cond->string); + } + else + { + /* [ "!" | "=" ] - check field valid */ + new_cond->type = insn_field_cond_field; + /* new_cond->field is determined in later */ + } + + /* Only a single `=' is permitted. */ + if ((new_cond->test == insn_field_cond_eq + && new_field->conditions != NULL) + || (new_field->conditions != NULL + && new_field->conditions->test == insn_field_cond_eq)) + error (line, "Only single conditional when `=' allowed\n"); + + /* insert it */ + { + insn_field_cond **last = &new_field->conditions; + while (*last != NULL) + last = &(*last)->next; + *last = new_cond; + } + } + + /* NOW verify that the field was finished */ + if (*chp == ',') + { + chp = skip_spaces (chp + 1); + if (*chp == '\0') + error (line, "empty field\n"); + } + else if (*chp != '\0') + { + error (line, "Missing field separator\n"); + } + + /* copy the value */ + new_field->val_string = NZALLOC (char, strlen_val + 1); + strncpy (new_field->val_string, start_val, strlen_val); + if (isdigit (new_field->val_string[0])) + { + if (strlen_pos == 0) + { + /* when the length/pos field is omited, an integer field + is always binary */ + unsigned64 val = 0; + int i; + for (i = 0; i < strlen_val; i++) + { + if (new_field->val_string[i] != '0' + && new_field->val_string[i] != '1') + error (line, "invalid binary field %s\n", + new_field->val_string); + val = (val << 1) + (new_field->val_string[i] == '1'); + } + new_field->val_int = val; + new_field->type = insn_field_int; + } + else + { + new_field->val_int = a2i (new_field->val_string); + new_field->type = insn_field_int; + } + } + else if (new_field->val_string[0] == '/') + { + new_field->type = insn_field_reserved; + } + else if (new_field->val_string[0] == '*') + { + new_field->type = insn_field_wild; + } + else + { + new_field->type = insn_field_string; + if (filter_is_member (word->field_names, new_field->val_string)) + error (line, "Field name %s is duplicated\n", + new_field->val_string); + filter_parse (&word->field_names, new_field->val_string); + } + if (new_field->type != insn_field_string + && new_field->conditions != NULL) + error (line, "Conditionals can only be applied to named fields\n"); + + /* the copy the position */ + new_field->pos_string = NZALLOC (char, strlen_pos + 1); + strncpy (new_field->pos_string, start_pos, strlen_pos); + if (strlen_pos == 0) + { + new_field->first = new_field->prev->last + 1; + if (new_field->first == 0 /* first field */ + && *chp == '\0' /* no further fields */ + && new_field->type == insn_field_string) + { + /* A single string without any position, assume that it + represents the entire instruction word */ + new_field->width = options.insn_bit_size; + } + else + { + /* No explicit width/position, assume value implicitly + supplies the width */ + new_field->width = strlen_val; + } + new_field->last = new_field->first + new_field->width - 1; + if (new_field->last >= options.insn_bit_size) + error (line, "Bit position %d exceed instruction bit size (%d)\n", + new_field->last, options.insn_bit_size); + } + else if (options.insn_specifying_widths) + { + new_field->first = new_field->prev->last + 1; + new_field->width = a2i (new_field->pos_string); + new_field->last = new_field->first + new_field->width - 1; + if (new_field->last >= options.insn_bit_size) + error (line, "Bit position %d exceed instruction bit size (%d)\n", + new_field->last, options.insn_bit_size); + } + else + { + new_field->first = target_a2i (options.hi_bit_nr, + new_field->pos_string); + new_field->last = new_field->next->first - 1; /* guess */ + new_field->width = new_field->last - new_field->first + 1; /* guess */ + new_field->prev->last = new_field->first - 1; /*fix */ + new_field->prev->width = new_field->first - new_field->prev->first; /*fix */ + } + } + + /* fiddle first/last so that the sentinals disapear */ + ASSERT (word->first->last < 0); + ASSERT (word->last->first >= options.insn_bit_size); + word->first = word->first->next; + word->last = word->last->prev; + + /* check that the last field goes all the way to the last bit */ + if (word->last->last != options.insn_bit_size - 1) + { + if (options.warn.width) + options.warning (line, "Instruction format is not %d bits wide\n", + options.insn_bit_size); + word->last->last = options.insn_bit_size - 1; + } + + /* now go over this again, pointing each bit position at a field + record */ + { + insn_field_entry *field; + for (field = word->first; + field->last < options.insn_bit_size; field = field->next) + { + int i; + for (i = field->first; i <= field->last; i++) + { + word->bit[i] = ZALLOC (insn_bit_entry); + word->bit[i]->field = field; + switch (field->type) + { + case insn_field_invalid: + ASSERT (0); + break; + case insn_field_int: + word->bit[i]->mask = 1; + word->bit[i]->value = ((field->val_int + & ((insn_uint) 1 << + (field->last - i))) != 0); + case insn_field_reserved: + case insn_field_wild: + case insn_field_string: + /* if we encounter a constant conditional, encode + their bit value. */ + if (field->conditions != NULL + && field->conditions->test == insn_field_cond_eq + && field->conditions->type == insn_field_cond_value) + { + word->bit[i]->mask = 1; + word->bit[i]->value = ((field->conditions->value + & ((insn_uint) 1 << + (field->last - i))) != 0); + } + break; + } + } + } + } + + return word; +} + + +static void +parse_insn_words (insn_entry * insn, char *formats) +{ + insn_word_entry **last_word = &insn->words; + char *chp; + + /* now work through the formats */ + insn->nr_words = 0; + chp = formats; + + while (1) + { + char *start_pos; + char *end_pos; + int strlen_pos; + char *format; + insn_word_entry *new_word; + + /* skip leading spaces */ + chp = skip_spaces (chp); + + /* break out the format */ + start_pos = chp; + chp = skip_to_separator (chp, "+"); + end_pos = back_spaces (start_pos, chp); + strlen_pos = end_pos - start_pos; + + /* check that something was there */ + if (strlen_pos == 0) + error (insn->line, "missing or empty instruction format\n"); + + /* parse the field */ + format = NZALLOC (char, strlen_pos + 1); + strncpy (format, start_pos, strlen_pos); + new_word = parse_insn_word (insn->line, format, insn->nr_words); + insn->nr_words++; + if (filter_is_common (insn->field_names, new_word->field_names)) + error (insn->line, "Field name duplicated between two words\n"); + filter_add (&insn->field_names, new_word->field_names); + + /* insert it */ + *last_word = new_word; + last_word = &new_word->next; + + /* last format? */ + if (*chp == '\0') + break; + ASSERT (*chp == '+'); + chp++; + } + + /* create a quick access array (indexed by word) of the same structure */ + { + int i; + insn_word_entry *word; + insn->word = NZALLOC (insn_word_entry *, insn->nr_words + 1); + for (i = 0, word = insn->words; + i < insn->nr_words; i++, word = word->next) + insn->word[i] = word; + } + + /* Go over all fields that have conditionals refering to other + fields. Link the fields up. Verify that the two fields have the + same size. Verify that the two fields are different */ + { + int i; + for (i = 0; i < insn->nr_words; i++) + { + insn_word_entry *word = insn->word[i]; + insn_field_entry *f; + for (f = word->first; f->last < options.insn_bit_size; f = f->next) + { + insn_field_cond *cond; + for (cond = f->conditions; cond != NULL; cond = cond->next) + { + if (cond->type == insn_field_cond_field) + { + int j; + if (strcmp (cond->string, f->val_string) == 0) + error (insn->line, + "Conditional `%s' of field `%s' refers to its self\n", + cond->string, f->val_string); + for (j = 0; j <= i && cond->field == NULL; j++) + { + insn_word_entry *refered_word = insn->word[j]; + insn_field_entry *refered_field; + for (refered_field = refered_word->first; + refered_field != NULL && cond->field == NULL; + refered_field = refered_field->next) + { + if (refered_field->type == insn_field_string + && strcmp (refered_field->val_string, + cond->string) == 0) + { + /* found field being refered to by conditonal */ + cond->field = refered_field; + /* check refered to and this field are + the same size */ + if (f->width != refered_field->width) + error (insn->line, + "Conditional `%s' of field `%s' should be of size %s\n", + cond->string, f->val_string, + refered_field->width); + } + } + } + if (cond->field == NULL) + error (insn->line, + "Conditional `%s' of field `%s' not yet defined\n", + cond->string, f->val_string); + } + } + } + } + } + +} + +typedef enum +{ + unknown_record = 0, + insn_record, /* default */ + code_record, + cache_record, + compute_record, + scratch_record, + option_record, + string_function_record, + function_record, + internal_record, + define_record, + include_record, + model_processor_record, + model_macro_record, + model_data_record, + model_static_record, + model_function_record, + model_internal_record, +} +insn_record_type; + +static const name_map insn_type_map[] = { + {"option", option_record}, + {"cache", cache_record}, + {"compute", compute_record}, + {"scratch", scratch_record}, + {"define", define_record}, + {"include", include_record}, + {"%s", string_function_record}, + {"function", function_record}, + {"internal", internal_record}, + {"model", model_processor_record}, + {"model-macro", model_macro_record}, + {"model-data", model_data_record}, + {"model-static", model_static_record}, + {"model-internal", model_internal_record}, + {"model-function", model_function_record}, + {NULL, insn_record}, +}; + + +static int +record_is_old (table_entry *entry) +{ + if (entry->nr_fields > record_type_field + && strlen (entry->field[record_type_field]) == 0) + return 1; + return 0; +} + +static insn_record_type +record_type (table_entry *entry) +{ + switch (entry->type) + { + case table_code_entry: + return code_record; + + case table_colon_entry: + if (record_is_old (entry)) + { + /* old-format? */ + if (entry->nr_fields > old_record_type_field) + { + int i = name2i (entry->field[old_record_type_field], + insn_type_map); + return i; + } + else + { + return unknown_record; + } + } + else if (entry->nr_fields > record_type_field + && entry->field[0][0] == '\0') + { + /* new-format? */ + int i = name2i (entry->field[record_type_field], + insn_type_map); + return i; + } + else + return insn_record; /* default */ + } + return unknown_record; +} + +static int +record_prefix_is (table_entry *entry, char ch, int nr_fields) +{ + if (entry->type != table_colon_entry) + return 0; + if (entry->nr_fields < nr_fields) + return 0; + if (entry->field[0][0] != ch && ch != '\0') + return 0; + return 1; +} + +static table_entry * +parse_model_data_record (insn_table *isa, + table *file, + table_entry *record, + int nr_fields, model_data **list) +{ + table_entry *model_record = record; + table_entry *code_record = NULL; + model_data *new_data; + if (record->nr_fields < nr_fields) + error (record->line, "Incorrect number of fields\n"); + record = table_read (file); + if (record->type == table_code_entry) + { + code_record = record; + record = table_read (file); + } + /* create the new data record */ + new_data = ZALLOC (model_data); + new_data->line = model_record->line; + filter_parse (&new_data->flags, + model_record->field[record_filter_flags_field]); + new_data->entry = model_record; + new_data->code = code_record; + /* append it if not filtered out */ + if (!is_filtered_out (options.flags_filter, + model_record->field[record_filter_flags_field]) + && !is_filtered_out (options.model_filter, + model_record->field[record_filter_models_field])) + { + while (*list != NULL) + list = &(*list)->next; + *list = new_data; + } + return record; +} + + +typedef enum +{ + insn_bit_size_option = 1, + insn_specifying_widths_option, + hi_bit_nr_option, + flags_filter_option, + model_filter_option, + multi_sim_option, + format_names_option, + gen_delayed_branch, + unknown_option, +} +option_names; + +static const name_map option_map[] = { + {"insn-bit-size", insn_bit_size_option}, + {"insn-specifying-widths", insn_specifying_widths_option}, + {"hi-bit-nr", hi_bit_nr_option}, + {"flags-filter", flags_filter_option}, + {"model-filter", model_filter_option}, + {"multi-sim", multi_sim_option}, + {"format-names", format_names_option}, + {"gen-delayed-branch", gen_delayed_branch}, + {NULL, unknown_option}, +}; + +static table_entry * +parse_include_record (table *file, table_entry *record) +{ + /* parse the include record */ + if (record->nr_fields < nr_include_fields) + error (record->line, "Incorrect nr fields for include record\n"); + /* process it */ + if (!is_filtered_out (options.flags_filter, + record->field[record_filter_flags_field]) + && !is_filtered_out (options.model_filter, + record->field[record_filter_models_field])) + { + table_push (file, record->line, options.include, + record->field[include_filename_field]); + } + /* nb: can't read next record until after the file has been pushed */ + record = table_read (file); + return record; +} + + +static table_entry * +parse_option_record (table *file, table_entry *record) +{ + table_entry *option_record; + /* parse the option record */ + option_record = record; + if (record->nr_fields < nr_option_fields) + error (record->line, "Incorrect nr of fields for option record\n"); + record = table_read (file); + /* process it */ + if (!is_filtered_out (options.flags_filter, + option_record->field[record_filter_flags_field]) + && !is_filtered_out (options.model_filter, + option_record->field[record_filter_models_field])) + { + char *name = option_record->field[option_name_field]; + option_names option = name2i (name, option_map); + char *value = option_record->field[option_value_field]; + switch (option) + { + case insn_bit_size_option: + { + options.insn_bit_size = a2i (value); + if (options.insn_bit_size < 0 + || options.insn_bit_size > max_insn_bit_size) + error (option_record->line, + "Instruction bit size out of range\n"); + if (options.hi_bit_nr != options.insn_bit_size - 1 + && options.hi_bit_nr != 0) + error (option_record->line, + "insn-bit-size / hi-bit-nr conflict\n"); + break; + } + case insn_specifying_widths_option: + { + options.insn_specifying_widths = a2i (value); + break; + } + case hi_bit_nr_option: + { + options.hi_bit_nr = a2i (value); + if (options.hi_bit_nr != 0 + && options.hi_bit_nr != options.insn_bit_size - 1) + error (option_record->line, + "hi-bit-nr / insn-bit-size conflict\n"); + break; + } + case flags_filter_option: + { + filter_parse (&options.flags_filter, value); + break; + } + case model_filter_option: + { + filter_parse (&options.model_filter, value); + break; + } + case multi_sim_option: + { + options.gen.multi_sim = a2i (value); + break; + } + case format_names_option: + { + filter_parse (&options.format_name_filter, value); + break; + } + case gen_delayed_branch: + { + options.gen.delayed_branch = a2i (value); + break; + } + case unknown_option: + { + error (option_record->line, "Unknown option - %s\n", name); + break; + } + } + } + return record; +} + + +static table_entry * +parse_function_record (table *file, + table_entry *record, + function_entry ** list, + function_entry ** list_entry, + int is_internal, model_table *model) +{ + function_entry *new_function; + new_function = ZALLOC (function_entry); + new_function->line = record->line; + new_function->is_internal = is_internal; + /* parse the function header */ + if (record_is_old (record)) + { + if (record->nr_fields < nr_old_function_fields) + error (record->line, "Missing fields from (old) function record\n"); + new_function->type = record->field[old_function_typedef_field]; + new_function->type = record->field[old_function_typedef_field]; + if (record->nr_fields > old_function_param_field) + new_function->param = record->field[old_function_param_field]; + new_function->name = record->field[old_function_name_field]; + } + else + { + if (record->nr_fields < nr_function_fields) + error (record->line, "Missing fields from function record\n"); + filter_parse (&new_function->flags, + record->field[record_filter_flags_field]); + filter_parse (&new_function->models, + record->field[record_filter_models_field]); + new_function->type = record->field[function_typedef_field]; + new_function->param = record->field[function_param_field]; + new_function->name = record->field[function_name_field]; + } + record = table_read (file); + /* parse any function-model records */ + while (record != NULL + && record_prefix_is (record, '*', nr_function_model_fields)) + { + char *model_name = record->field[function_model_name_field] + 1; /*skip `*' */ + filter_parse (&new_function->models, model_name); + if (!filter_is_subset (model->processors, new_function->models)) + { + error (record->line, "machine model `%s' undefined\n", model_name); + } + record = table_read (file); + } + /* parse the function body */ + if (record->type == table_code_entry) + { + new_function->code = record; + record = table_read (file); + } + /* insert it */ + if (!filter_is_subset (options.flags_filter, new_function->flags)) + { + if (options.warn.discard) + notify (new_function->line, "Discarding function %s - filter flags\n", + new_function->name); + } + else if (new_function->models != NULL + && !filter_is_common (options.model_filter, new_function->models)) + { + if (options.warn.discard) + notify (new_function->line, + "Discarding function %s - filter models\n", + new_function->name); + } + else + { + while (*list != NULL) + list = &(*list)->next; + *list = new_function; + if (list_entry != NULL) + *list_entry = new_function; + } + /* done */ + return record; +} + +static void +parse_insn_model_record (table *file, + table_entry *record, + insn_entry * insn, model_table *model) +{ + insn_model_entry **last_insn_model; + insn_model_entry *new_insn_model = ZALLOC (insn_model_entry); + /* parse it */ + new_insn_model->line = record->line; + if (record->nr_fields > insn_model_unit_data_field) + new_insn_model->unit_data = record->field[insn_model_unit_data_field]; + new_insn_model->insn = insn; + /* parse the model names, verify that all were defined */ + new_insn_model->names = NULL; + filter_parse (&new_insn_model->names, + record->field[insn_model_name_field] + 1 /*skip `*' */ ); + if (new_insn_model->names == NULL) + { + /* No processor names - a generic model entry, enter it into all + the non-empty fields */ + int index; + for (index = 0; index < model->nr_models; index++) + if (insn->model[index] == 0) + { + insn->model[index] = new_insn_model; + } + /* also add the complete processor set to this processor's set */ + filter_add (&insn->processors, model->processors); + } + else + { + /* Find the corresponding master model record for each name so + that they can be linked in. */ + int index; + char *name = ""; + while (1) + { + name = filter_next (new_insn_model->names, name); + if (name == NULL) + break; + index = filter_is_member (model->processors, name) - 1; + if (index < 0) + { + error (new_insn_model->line, + "machine model `%s' undefined\n", name); + } + /* store it in the corresponding model array entry */ + if (insn->model[index] != NULL && insn->model[index]->names != NULL) + { + warning (new_insn_model->line, + "machine model `%s' previously defined\n", name); + error (insn->model[index]->line, "earlier definition\n"); + } + insn->model[index] = new_insn_model; + /* also add the name to the instructions processor set as an + alternative lookup mechanism */ + filter_parse (&insn->processors, name); + } + } +#if 0 + /* for some reason record the max length of any + function unit field */ + int len = strlen (insn_model_ptr->field[insn_model_fields]); + if (model->max_model_fields_len < len) + model->max_model_fields_len = len; +#endif + /* link it in */ + last_insn_model = &insn->models; + while ((*last_insn_model) != NULL) + last_insn_model = &(*last_insn_model)->next; + *last_insn_model = new_insn_model; +} + + +static void +parse_insn_mnemonic_record (table *file, + table_entry *record, insn_entry * insn) +{ + insn_mnemonic_entry **last_insn_mnemonic; + insn_mnemonic_entry *new_insn_mnemonic = ZALLOC (insn_mnemonic_entry); + /* parse it */ + new_insn_mnemonic->line = record->line; + ASSERT (record->nr_fields > insn_mnemonic_format_field); + new_insn_mnemonic->format = record->field[insn_mnemonic_format_field]; + ASSERT (new_insn_mnemonic->format[0] == '"'); + if (new_insn_mnemonic->format[strlen (new_insn_mnemonic->format) - 1] != + '"') + error (new_insn_mnemonic->line, + "Missing closing double quote in mnemonic field\n"); + if (record->nr_fields > insn_mnemonic_condition_field) + new_insn_mnemonic->condition = + record->field[insn_mnemonic_condition_field]; + new_insn_mnemonic->insn = insn; + /* insert it */ + last_insn_mnemonic = &insn->mnemonics; + while ((*last_insn_mnemonic) != NULL) + last_insn_mnemonic = &(*last_insn_mnemonic)->next; + insn->nr_mnemonics++; + *last_insn_mnemonic = new_insn_mnemonic; +} + + +static table_entry * +parse_macro_record (table *file, table_entry *record) +{ +#if 1 + error (record->line, "Macros are not implemented"); +#else + /* parse the define record */ + if (record->nr_fields < nr_define_fields) + error (record->line, "Incorrect nr fields for define record\n"); + /* process it */ + if (!is_filtered_out (options.flags_filter, + record->field[record_filter_flags_field]) + && !is_filtered_out (options.model_filter, + record->field[record_filter_models_field])) + { + table_define (file, + record->line, + record->field[macro_name_field], + record->field[macro_args_field], + record->field[macro_expr_field]); + } + record = table_read (file); +#endif + return record; +} + + +insn_table * +load_insn_table (char *file_name, cache_entry *cache) +{ + table *file = table_open (file_name); + table_entry *record = table_read (file); + + insn_table *isa = ZALLOC (insn_table); + model_table *model = ZALLOC (model_table); + + isa->model = model; + isa->caches = cache; + + while (record != NULL) + { + + switch (record_type (record)) + { + + case include_record: + { + record = parse_include_record (file, record); + break; + } + + case option_record: + { + if (isa->insns != NULL) + error (record->line, "Option after first instruction\n"); + record = parse_option_record (file, record); + break; + } + + case string_function_record: + { + function_entry *function = NULL; + record = parse_function_record (file, record, + &isa->functions, + &function, 0 /*is-internal */ , + model); + /* convert a string function record into an internal function */ + if (function != NULL) + { + char *name = NZALLOC (char, + (strlen ("str_") + + strlen (function->name) + 1)); + strcat (name, "str_"); + strcat (name, function->name); + function->name = name; + function->type = "const char *"; + } + break; + } + + case function_record: /* function record */ + { + record = parse_function_record (file, record, + &isa->functions, + NULL, 0 /*is-internal */ , + model); + break; + } + + case internal_record: + { + /* only insert it into the function list if it is unknown */ + function_entry *function = NULL; + record = parse_function_record (file, record, + &isa->functions, + &function, 1 /*is-internal */ , + model); + /* check what was inserted to see if a pseudo-instruction + entry also needs to be created */ + if (function != NULL) + { + insn_entry **insn = NULL; + if (strcmp (function->name, "illegal") == 0) + { + /* illegal function save it away */ + if (isa->illegal_insn != NULL) + { + warning (function->line, + "Multiple illegal instruction definitions\n"); + error (isa->illegal_insn->line, + "Location of first illegal instruction\n"); + } + else + insn = &isa->illegal_insn; + } + if (insn != NULL) + { + *insn = ZALLOC (insn_entry); + (*insn)->line = function->line; + (*insn)->name = function->name; + (*insn)->code = function->code; + } + } + break; + } + + case scratch_record: /* cache macro records */ + case cache_record: + case compute_record: + { + cache_entry *new_cache; + /* parse the cache record */ + if (record->nr_fields < nr_cache_fields) + error (record->line, + "Incorrect nr of fields for scratch/cache/compute record\n"); + /* create it */ + new_cache = ZALLOC (cache_entry); + new_cache->line = record->line; + filter_parse (&new_cache->flags, + record->field[record_filter_flags_field]); + filter_parse (&new_cache->models, + record->field[record_filter_models_field]); + new_cache->type = record->field[cache_typedef_field]; + new_cache->name = record->field[cache_name_field]; + filter_parse (&new_cache->original_fields, + record->field[cache_original_fields_field]); + new_cache->expression = record->field[cache_expression_field]; + /* insert it but only if not filtered out */ + if (!filter_is_subset (options.flags_filter, new_cache->flags)) + { + notify (new_cache->line, + "Discarding cache entry %s - filter flags\n", + new_cache->name); + } + else if (is_filtered_out (options.model_filter, + record-> + field[record_filter_models_field])) + { + notify (new_cache->line, + "Discarding cache entry %s - filter models\n", + new_cache->name); + } + else + { + cache_entry **last; + last = &isa->caches; + while (*last != NULL) + last = &(*last)->next; + *last = new_cache; + } + /* advance things */ + record = table_read (file); + break; + } + + /* model records */ + case model_processor_record: + { + model_entry *new_model; + /* parse the model */ + if (record->nr_fields < nr_model_processor_fields) + error (record->line, + "Incorrect nr of fields for model record\n"); + if (isa->insns != NULL) + error (record->line, "Model appears after first instruction\n"); + new_model = ZALLOC (model_entry); + filter_parse (&new_model->flags, + record->field[record_filter_flags_field]); + new_model->line = record->line; + new_model->name = record->field[model_name_field]; + new_model->full_name = record->field[model_full_name_field]; + new_model->unit_data = record->field[model_unit_data_field]; + /* only insert it if not filtered out */ + if (!filter_is_subset (options.flags_filter, new_model->flags)) + { + notify (new_model->line, + "Discarding processor model %s - filter flags\n", + new_model->name); + } + else if (is_filtered_out (options.model_filter, + record-> + field[record_filter_models_field])) + { + notify (new_model->line, + "Discarding processor model %s - filter models\n", + new_model->name); + } + else if (filter_is_member (model->processors, new_model->name)) + { + error (new_model->line, "Duplicate processor model %s\n", + new_model->name); + } + else + { + model_entry **last; + last = &model->models; + while (*last != NULL) + last = &(*last)->next; + *last = new_model; + /* count it */ + model->nr_models++; + filter_parse (&model->processors, new_model->name); + } + /* advance things */ + record = table_read (file); + } + break; + + case model_macro_record: + record = parse_model_data_record (isa, file, record, + nr_model_macro_fields, + &model->macros); + break; + + case model_data_record: + record = parse_model_data_record (isa, file, record, + nr_model_data_fields, + &model->data); + break; + + case model_static_record: + record = parse_function_record (file, record, + &model->statics, + NULL, 0 /*is internal */ , + model); + break; + + case model_internal_record: + record = parse_function_record (file, record, + &model->internals, + NULL, 1 /*is internal */ , + model); + break; + + case model_function_record: + record = parse_function_record (file, record, + &model->functions, + NULL, 0 /*is internal */ , + model); + break; + + case insn_record: /* instruction records */ + { + insn_entry *new_insn; + char *format; + /* parse the instruction */ + if (record->nr_fields < nr_insn_fields) + error (record->line, + "Incorrect nr of fields for insn record\n"); + new_insn = ZALLOC (insn_entry); + new_insn->line = record->line; + filter_parse (&new_insn->flags, + record->field[record_filter_flags_field]); + /* save the format field. Can't parse it until after the + filter-out checks. Could be filtered out because the + format is invalid */ + format = record->field[insn_word_field]; + new_insn->format_name = record->field[insn_format_name_field]; + if (options.format_name_filter != NULL + && !filter_is_member (options.format_name_filter, + new_insn->format_name)) + error (new_insn->line, + "Unreconized instruction format name `%s'\n", + new_insn->format_name); + filter_parse (&new_insn->options, + record->field[insn_options_field]); + new_insn->name = record->field[insn_name_field]; + record = table_read (file); + /* Parse any model/assember records */ + new_insn->nr_models = model->nr_models; + new_insn->model = + NZALLOC (insn_model_entry *, model->nr_models + 1); + while (record != NULL) + { + if (record_prefix_is (record, '*', nr_insn_model_fields)) + parse_insn_model_record (file, record, new_insn, model); + else + if (record_prefix_is (record, '"', nr_insn_mnemonic_fields)) + parse_insn_mnemonic_record (file, record, new_insn); + else + break; + /* advance */ + record = table_read (file); + } + /* Parse the code record */ + if (record != NULL && record->type == table_code_entry) + { + new_insn->code = record; + record = table_read (file); + } + else if (options.warn.unimplemented) + notify (new_insn->line, "unimplemented\n"); + /* insert it */ + if (!filter_is_subset (options.flags_filter, new_insn->flags)) + { + if (options.warn.discard) + notify (new_insn->line, + "Discarding instruction %s (flags-filter)\n", + new_insn->name); + } + else if (new_insn->processors != NULL + && options.model_filter != NULL + && !filter_is_common (options.model_filter, + new_insn->processors)) + { + /* only discard an instruction based in the processor + model when both the instruction and the options are + nonempty */ + if (options.warn.discard) + notify (new_insn->line, + "Discarding instruction %s (processor-model)\n", + new_insn->name); + } + else + { + insn_entry **last; + /* finish the parsing */ + parse_insn_words (new_insn, format); + /* append it */ + last = &isa->insns; + while (*last) + last = &(*last)->next; + *last = new_insn; + /* update global isa counters */ + isa->nr_insns++; + if (isa->max_nr_words < new_insn->nr_words) + isa->max_nr_words = new_insn->nr_words; + filter_add (&isa->flags, new_insn->flags); + filter_add (&isa->options, new_insn->options); + } + break; + } + + case define_record: + record = parse_macro_record (file, record); + break; + + case unknown_record: + case code_record: + error (record->line, "Unknown or unexpected entry\n"); + + + } + } + return isa; +} + + +void +print_insn_words (lf *file, insn_entry * insn) +{ + insn_word_entry *word = insn->words; + if (word != NULL) + { + while (1) + { + insn_field_entry *field = word->first; + while (1) + { + if (options.insn_specifying_widths) + lf_printf (file, "%d.", field->width); + else + lf_printf (file, "%d.", + i2target (options.hi_bit_nr, field->first)); + switch (field->type) + { + case insn_field_invalid: + ASSERT (0); + break; + case insn_field_int: + lf_printf (file, "0x%lx", (long) field->val_int); + break; + case insn_field_reserved: + lf_printf (file, "/"); + break; + case insn_field_wild: + lf_printf (file, "*"); + break; + case insn_field_string: + lf_printf (file, "%s", field->val_string); + break; + } + if (field == word->last) + break; + field = field->next; + lf_printf (file, ","); + } + word = word->next; + if (word == NULL) + break; + lf_printf (file, "+"); + } + } +} + + + +void +function_entry_traverse (lf *file, + function_entry * functions, + function_entry_handler * handler, void *data) +{ + function_entry *function; + for (function = functions; function != NULL; function = function->next) + { + handler (file, function, data); + } +} + +void +insn_table_traverse_insn (lf *file, + insn_table *isa, + insn_entry_handler * handler, void *data) +{ + insn_entry *insn; + for (insn = isa->insns; insn != NULL; insn = insn->next) + { + handler (file, isa, insn, data); + } +} + + +static void +dump_function_entry (lf *file, + char *prefix, function_entry * entry, char *suffix) +{ + lf_printf (file, "%s(function_entry *) 0x%lx", prefix, (long) entry); + if (entry != NULL) + { + dump_line_ref (file, "\n(line ", entry->line, ")"); + dump_filter (file, "\n(flags ", entry->flags, ")"); + lf_printf (file, "\n(type \"%s\")", entry->type); + lf_printf (file, "\n(name \"%s\")", entry->name); + lf_printf (file, "\n(param \"%s\")", entry->param); + dump_table_entry (file, "\n(code ", entry->code, ")"); + lf_printf (file, "\n(is_internal %d)", entry->is_internal); + lf_printf (file, "\n(next 0x%lx)", (long) entry->next); + } + lf_printf (file, "%s", suffix); +} + +static void +dump_function_entries (lf *file, + char *prefix, function_entry * entry, char *suffix) +{ + lf_printf (file, "%s", prefix); + lf_indent (file, +1); + while (entry != NULL) + { + dump_function_entry (file, "\n(", entry, ")"); + entry = entry->next; + } + lf_indent (file, -1); + lf_printf (file, "%s", suffix); +} + +static char * +cache_entry_type_to_str (cache_entry_type type) +{ + switch (type) + { + case scratch_value: + return "scratch"; + case cache_value: + return "cache"; + case compute_value: + return "compute"; + } + ERROR ("Bad switch"); + return 0; +} + +static void +dump_cache_entry (lf *file, char *prefix, cache_entry *entry, char *suffix) +{ + lf_printf (file, "%s(cache_entry *) 0x%lx", prefix, (long) entry); + if (entry != NULL) + { + dump_line_ref (file, "\n(line ", entry->line, ")"); + dump_filter (file, "\n(flags ", entry->flags, ")"); + lf_printf (file, "\n(entry_type \"%s\")", + cache_entry_type_to_str (entry->entry_type)); + lf_printf (file, "\n(name \"%s\")", entry->name); + dump_filter (file, "\n(original_fields ", entry->original_fields, ")"); + lf_printf (file, "\n(type \"%s\")", entry->type); + lf_printf (file, "\n(expression \"%s\")", entry->expression); + lf_printf (file, "\n(next 0x%lx)", (long) entry->next); + } + lf_printf (file, "%s", suffix); +} + +void +dump_cache_entries (lf *file, char *prefix, cache_entry *entry, char *suffix) +{ + lf_printf (file, "%s", prefix); + lf_indent (file, +1); + while (entry != NULL) + { + dump_cache_entry (file, "\n(", entry, ")"); + entry = entry->next; + } + lf_indent (file, -1); + lf_printf (file, "%s", suffix); +} + +static void +dump_model_data (lf *file, char *prefix, model_data *entry, char *suffix) +{ + lf_printf (file, "%s(model_data *) 0x%lx", prefix, (long) entry); + if (entry != NULL) + { + lf_indent (file, +1); + dump_line_ref (file, "\n(line ", entry->line, ")"); + dump_filter (file, "\n(flags ", entry->flags, ")"); + dump_table_entry (file, "\n(entry ", entry->entry, ")"); + dump_table_entry (file, "\n(code ", entry->code, ")"); + lf_printf (file, "\n(next 0x%lx)", (long) entry->next); + lf_indent (file, -1); + } + lf_printf (file, "%s", prefix); +} + +static void +dump_model_datas (lf *file, char *prefix, model_data *entry, char *suffix) +{ + lf_printf (file, "%s", prefix); + lf_indent (file, +1); + while (entry != NULL) + { + dump_model_data (file, "\n(", entry, ")"); + entry = entry->next; + } + lf_indent (file, -1); + lf_printf (file, "%s", suffix); +} + +static void +dump_model_entry (lf *file, char *prefix, model_entry *entry, char *suffix) +{ + lf_printf (file, "%s(model_entry *) 0x%lx", prefix, (long) entry); + if (entry != NULL) + { + lf_indent (file, +1); + dump_line_ref (file, "\n(line ", entry->line, ")"); + dump_filter (file, "\n(flags ", entry->flags, ")"); + lf_printf (file, "\n(name \"%s\")", entry->name); + lf_printf (file, "\n(full_name \"%s\")", entry->full_name); + lf_printf (file, "\n(unit_data \"%s\")", entry->unit_data); + lf_printf (file, "\n(next 0x%lx)", (long) entry->next); + lf_indent (file, -1); + } + lf_printf (file, "%s", prefix); +} + +static void +dump_model_entries (lf *file, char *prefix, model_entry *entry, char *suffix) +{ + lf_printf (file, "%s", prefix); + lf_indent (file, +1); + while (entry != NULL) + { + dump_model_entry (file, "\n(", entry, ")"); + entry = entry->next; + } + lf_indent (file, -1); + lf_printf (file, "%s", suffix); +} + + +static void +dump_model_table (lf *file, char *prefix, model_table *entry, char *suffix) +{ + lf_printf (file, "%s(model_table *) 0x%lx", prefix, (long) entry); + if (entry != NULL) + { + lf_indent (file, +1); + dump_filter (file, "\n(processors ", entry->processors, ")"); + lf_printf (file, "\n(nr_models %d)", entry->nr_models); + dump_model_entries (file, "\n(models ", entry->models, ")"); + dump_model_datas (file, "\n(macros ", entry->macros, ")"); + dump_model_datas (file, "\n(data ", entry->data, ")"); + dump_function_entries (file, "\n(statics ", entry->statics, ")"); + dump_function_entries (file, "\n(internals ", entry->functions, ")"); + dump_function_entries (file, "\n(functions ", entry->functions, ")"); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + + +static char * +insn_field_type_to_str (insn_field_type type) +{ + switch (type) + { + case insn_field_invalid: + ASSERT (0); + return "(invalid)"; + case insn_field_int: + return "int"; + case insn_field_reserved: + return "reserved"; + case insn_field_wild: + return "wild"; + case insn_field_string: + return "string"; + } + ERROR ("bad switch"); + return 0; +} + +void +dump_insn_field (lf *file, + char *prefix, insn_field_entry *field, char *suffix) +{ + char *sep = " "; + lf_printf (file, "%s(insn_field_entry *) 0x%lx", prefix, (long) field); + if (field != NULL) + { + lf_indent (file, +1); + lf_printf (file, "%s(first %d)", sep, field->first); + lf_printf (file, "%s(last %d)", sep, field->last); + lf_printf (file, "%s(width %d)", sep, field->width); + lf_printf (file, "%s(type %s)", sep, + insn_field_type_to_str (field->type)); + switch (field->type) + { + case insn_field_invalid: + ASSERT (0); + break; + case insn_field_int: + lf_printf (file, "%s(val 0x%lx)", sep, (long) field->val_int); + break; + case insn_field_reserved: + /* nothing output */ + break; + case insn_field_wild: + /* nothing output */ + break; + case insn_field_string: + lf_printf (file, "%s(val \"%s\")", sep, field->val_string); + break; + } + lf_printf (file, "%s(next 0x%lx)", sep, (long) field->next); + lf_printf (file, "%s(prev 0x%lx)", sep, (long) field->prev); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + +void +dump_insn_word_entry (lf *file, + char *prefix, insn_word_entry *word, char *suffix) +{ + lf_printf (file, "%s(insn_word_entry *) 0x%lx", prefix, (long) word); + if (word != NULL) + { + int i; + insn_field_entry *field; + lf_indent (file, +1); + lf_printf (file, "\n(first 0x%lx)", (long) word->first); + lf_printf (file, "\n(last 0x%lx)", (long) word->last); + lf_printf (file, "\n(bit"); + for (i = 0; i < options.insn_bit_size; i++) + lf_printf (file, "\n ((value %d) (mask %d) (field 0x%lx))", + word->bit[i]->value, word->bit[i]->mask, + (long) word->bit[i]->field); + lf_printf (file, ")"); + for (field = word->first; field != NULL; field = field->next) + dump_insn_field (file, "\n(", field, ")"); + dump_filter (file, "\n(field_names ", word->field_names, ")"); + lf_printf (file, "\n(next 0x%lx)", (long) word->next); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + +static void +dump_insn_word_entries (lf *file, + char *prefix, insn_word_entry *word, char *suffix) +{ + lf_printf (file, "%s", prefix); + while (word != NULL) + { + dump_insn_word_entry (file, "\n(", word, ")"); + word = word->next; + } + lf_printf (file, "%s", suffix); +} + +static void +dump_insn_model_entry (lf *file, + char *prefix, insn_model_entry *model, char *suffix) +{ + lf_printf (file, "%s(insn_model_entry *) 0x%lx", prefix, (long) model); + if (model != NULL) + { + lf_indent (file, +1); + dump_line_ref (file, "\n(line ", model->line, ")"); + dump_filter (file, "\n(names ", model->names, ")"); + lf_printf (file, "\n(full_name \"%s\")", model->full_name); + lf_printf (file, "\n(unit_data \"%s\")", model->unit_data); + lf_printf (file, "\n(insn (insn_entry *) 0x%lx)", (long) model->insn); + lf_printf (file, "\n(next (insn_model_entry *) 0x%lx)", + (long) model->next); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + +static void +dump_insn_model_entries (lf *file, + char *prefix, insn_model_entry *model, char *suffix) +{ + lf_printf (file, "%s", prefix); + while (model != NULL) + { + dump_insn_model_entry (file, "\n", model, ""); + model = model->next; + } + lf_printf (file, "%s", suffix); +} + + +static void +dump_insn_mnemonic_entry (lf *file, + char *prefix, + insn_mnemonic_entry *mnemonic, char *suffix) +{ + lf_printf (file, "%s(insn_mnemonic_entry *) 0x%lx", prefix, + (long) mnemonic); + if (mnemonic != NULL) + { + lf_indent (file, +1); + dump_line_ref (file, "\n(line ", mnemonic->line, ")"); + lf_printf (file, "\n(format \"%s\")", mnemonic->format); + lf_printf (file, "\n(condition \"%s\")", mnemonic->condition); + lf_printf (file, "\n(insn (insn_entry *) 0x%lx)", + (long) mnemonic->insn); + lf_printf (file, "\n(next (insn_mnemonic_entry *) 0x%lx)", + (long) mnemonic->next); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + +static void +dump_insn_mnemonic_entries (lf *file, + char *prefix, + insn_mnemonic_entry *mnemonic, char *suffix) +{ + lf_printf (file, "%s", prefix); + while (mnemonic != NULL) + { + dump_insn_mnemonic_entry (file, "\n", mnemonic, ""); + mnemonic = mnemonic->next; + } + lf_printf (file, "%s", suffix); +} + +void +dump_insn_entry (lf *file, char *prefix, insn_entry * entry, char *suffix) +{ + lf_printf (file, "%s(insn_entry *) 0x%lx", prefix, (long) entry); + if (entry != NULL) + { + int i; + lf_indent (file, +1); + dump_line_ref (file, "\n(line ", entry->line, ")"); + dump_filter (file, "\n(flags ", entry->flags, ")"); + lf_printf (file, "\n(nr_words %d)", entry->nr_words); + dump_insn_word_entries (file, "\n(words ", entry->words, ")"); + lf_printf (file, "\n(word"); + for (i = 0; i < entry->nr_models; i++) + lf_printf (file, " 0x%lx", (long) entry->word[i]); + lf_printf (file, ")"); + dump_filter (file, "\n(field_names ", entry->field_names, ")"); + lf_printf (file, "\n(format_name \"%s\")", entry->format_name); + dump_filter (file, "\n(options ", entry->options, ")"); + lf_printf (file, "\n(name \"%s\")", entry->name); + lf_printf (file, "\n(nr_models %d)", entry->nr_models); + dump_insn_model_entries (file, "\n(models ", entry->models, ")"); + lf_printf (file, "\n(model"); + for (i = 0; i < entry->nr_models; i++) + lf_printf (file, " 0x%lx", (long) entry->model[i]); + lf_printf (file, ")"); + dump_filter (file, "\n(processors ", entry->processors, ")"); + dump_insn_mnemonic_entries (file, "\n(mnemonics ", entry->mnemonics, + ")"); + dump_table_entry (file, "\n(code ", entry->code, ")"); + lf_printf (file, "\n(next 0x%lx)", (long) entry->next); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + +static void +dump_insn_entries (lf *file, char *prefix, insn_entry * entry, char *suffix) +{ + lf_printf (file, "%s", prefix); + lf_indent (file, +1); + while (entry != NULL) + { + dump_insn_entry (file, "\n(", entry, ")"); + entry = entry->next; + } + lf_indent (file, -1); + lf_printf (file, "%s", suffix); +} + + + +void +dump_insn_table (lf *file, char *prefix, insn_table *isa, char *suffix) +{ + lf_printf (file, "%s(insn_table *) 0x%lx", prefix, (long) isa); + if (isa != NULL) + { + lf_indent (file, +1); + dump_cache_entries (file, "\n(caches ", isa->caches, ")"); + lf_printf (file, "\n(nr_insns %d)", isa->nr_insns); + lf_printf (file, "\n(max_nr_words %d)", isa->max_nr_words); + dump_insn_entries (file, "\n(insns ", isa->insns, ")"); + dump_function_entries (file, "\n(functions ", isa->functions, ")"); + dump_insn_entry (file, "\n(illegal_insn ", isa->illegal_insn, ")"); + dump_model_table (file, "\n(model ", isa->model, ")"); + dump_filter (file, "\n(flags ", isa->flags, ")"); + dump_filter (file, "\n(options ", isa->options, ")"); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + +#ifdef MAIN + +igen_options options; + +int +main (int argc, char **argv) +{ + insn_table *isa; + lf *l; + + INIT_OPTIONS (options); + + if (argc == 3) + filter_parse (&options.flags_filter, argv[2]); + else if (argc != 2) + error (NULL, "Usage: insn [ ]\n"); + + isa = load_insn_table (argv[1], NULL); + l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn"); + dump_insn_table (l, "(isa ", isa, ")\n"); + + return 0; +} + +#endif
ld-insn.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: ld-cache.h =================================================================== --- ld-cache.h (nonexistent) +++ ld-cache.h (revision 841) @@ -0,0 +1,66 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + + +/* For backward compatibility only - load a standalone cache macro table */ + +/* Instruction unpacking: + + Once the instruction has been decoded, the register (and other) + fields within the instruction need to be extracted. + + The table that follows determines how each field should be treated. + Importantly it considers the case where the extracted field is to + be used immediatly or stored in an instruction cache. + + + + Indicates what to do with the cache entry. If a cache is to be + used. SCRATCH and CACHE values are defined when a cache entry is + being filled while CACHE and COMPUTE values are defined in the + semantic code. + + Zero marks the end of the table. More importantly 1. indicates + that the entry is valid and can be cached. 2. indicates that that + the entry is valid but can not be cached. + + + + The field name as given in the instruction spec. + + + + A new name for once it has been extracted from the + instruction (and possibly stored in the instruction cache). + + + + String specifying the storage type for (the extracted + field>. + + + + Specifies how to get from . If null, old and + new name had better be the same. */ + + +extern cache_entry *load_cache_table (char *file_name);
ld-cache.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen-model.c =================================================================== --- gen-model.c (nonexistent) +++ gen-model.c (revision 841) @@ -0,0 +1,448 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +#include "misc.h" +#include "lf.h" +#include "table.h" + +#include "filter.h" + +#include "ld-decode.h" +#include "ld-insn.h" + +#include "gen-model.h" + +#ifndef NULL +#define NULL 0 +#endif + + +#if 0 +static void +model_c_or_h_data (insn_table *table, lf *file, table_entry *data) +{ + if (data->annex) + { + table_entry_print_cpp_line_nr (file, data->annex_line); + lf_print__c_code (file, data->annex); + lf_print__internal_reference (file); + lf_printf (file, "\n"); + } +} + +static void +model_c_or_h_function (insn_table *entry, + lf *file, table_entry *function, char *prefix) +{ + if (function->fields[function_type] == NULL + || function->fields[function_type][0] == '\0') + { + error ("Model function type not specified for %s", + function->fields[function_name]); + } + lf_printf (file, "\n"); + lf_print_function_type (file, function->fields[function_type], prefix, " "); + lf_printf (file, "%s\n(%s);\n", + function->fields[function_name], + function->fields[function_param]); + lf_printf (file, "\n"); +} + +void +gen_model_h (insn_table *table, lf *file) +{ + insn *insn_ptr; + model *model_ptr; + insn *macro; + char *name; + int model_create_p = 0; + int model_init_p = 0; + int model_halt_p = 0; + int model_mon_info_p = 0; + int model_mon_info_free_p = 0; + + for (macro = model_macros; macro; macro = macro->next) + { + model_c_or_h_data (table, file, macro->file_entry); + } + + lf_printf (file, "typedef enum _model_enum {\n"); + lf_printf (file, " MODEL_NONE,\n"); + for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) + { + lf_printf (file, " MODEL_%s,\n", model_ptr->name); + } + lf_printf (file, " nr_models\n"); + lf_printf (file, "} model_enum;\n"); + lf_printf (file, "\n"); + + lf_printf (file, "#define DEFAULT_MODEL MODEL_%s\n", + (models) ? models->name : "NONE"); + lf_printf (file, "\n"); + + lf_printf (file, "typedef struct _model_data model_data;\n"); + lf_printf (file, "typedef struct _model_time model_time;\n"); + lf_printf (file, "\n"); + + lf_printf (file, "extern model_enum current_model;\n"); + lf_printf (file, "extern const char *model_name[ (int)nr_models ];\n"); + lf_printf (file, + "extern const char *const *const model_func_unit_name[ (int)nr_models ];\n"); + lf_printf (file, + "extern const model_time *const model_time_mapping[ (int)nr_models ];\n"); + lf_printf (file, "\n"); + + for (insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) + { + model_c_or_h_function (table, file, insn_ptr->file_entry, + "INLINE_MODEL"); + name = insn_ptr->file_entry->fields[function_name]; + if (strcmp (name, "model_create") == 0) + model_create_p = 1; + else if (strcmp (name, "model_init") == 0) + model_init_p = 1; + else if (strcmp (name, "model_halt") == 0) + model_halt_p = 1; + else if (strcmp (name, "model_mon_info") == 0) + model_mon_info_p = 1; + else if (strcmp (name, "model_mon_info_free") == 0) + model_mon_info_free_p = 1; + } + + if (!model_create_p) + { + lf_print_function_type (file, "model_data *", "INLINE_MODEL", " "); + lf_printf (file, "model_create\n"); + lf_printf (file, "(sim_cpu *cpu);\n"); + lf_printf (file, "\n"); + } + + if (!model_init_p) + { + lf_print_function_type (file, "void", "INLINE_MODEL", " "); + lf_printf (file, "model_init\n"); + lf_printf (file, "(model_data *model_ptr);\n"); + lf_printf (file, "\n"); + } + + if (!model_halt_p) + { + lf_print_function_type (file, "void", "INLINE_MODEL", " "); + lf_printf (file, "model_halt\n"); + lf_printf (file, "(model_data *model_ptr);\n"); + lf_printf (file, "\n"); + } + + if (!model_mon_info_p) + { + lf_print_function_type (file, "model_print *", "INLINE_MODEL", " "); + lf_printf (file, "model_mon_info\n"); + lf_printf (file, "(model_data *model_ptr);\n"); + lf_printf (file, "\n"); + } + + if (!model_mon_info_free_p) + { + lf_print_function_type (file, "void", "INLINE_MODEL", " "); + lf_printf (file, "model_mon_info_free\n"); + lf_printf (file, "(model_data *model_ptr,\n"); + lf_printf (file, " model_print *info_ptr);\n"); + lf_printf (file, "\n"); + } + + lf_print_function_type (file, "void", "INLINE_MODEL", " "); + lf_printf (file, "model_set\n"); + lf_printf (file, "(const char *name);\n"); +} + +/****************************************************************/ + +typedef struct _model_c_passed_data model_c_passed_data; +struct _model_c_passed_data +{ + lf *file; + model *model_ptr; +}; + +static void +model_c_insn (insn_table *entry, + lf *phony_file, void *data, insn * instruction, int depth) +{ + model_c_passed_data *data_ptr = (model_c_passed_data *) data; + lf *file = data_ptr->file; + char *current_name = data_ptr->model_ptr->printable_name; + table_model_entry *model_ptr = instruction->file_entry->model_first; + + while (model_ptr) + { + if (model_ptr->fields[insn_model_name] == current_name) + { + lf_printf (file, " { %-*s }, /* %s */\n", + max_model_fields_len, + model_ptr->fields[insn_model_fields], + instruction->file_entry->fields[insn_name]); + return; + } + + model_ptr = model_ptr->next; + } + + lf_printf (file, " { %-*s }, /* %s */\n", + max_model_fields_len, + data_ptr->model_ptr->insn_default, + instruction->file_entry->fields[insn_name]); +} + +static void +model_c_function (insn_table *table, + lf *file, table_entry *function, const char *prefix) +{ + if (function->fields[function_type] == NULL + || function->fields[function_type][0] == '\0') + { + error ("Model function return type not specified for %s", + function->fields[function_name]); + } + else + { + lf_printf (file, "\n"); + lf_print_function_type (file, function->fields[function_type], prefix, + "\n"); + lf_printf (file, "%s(%s)\n", function->fields[function_name], + function->fields[function_param]); + } + lf_printf (file, "{\n"); + if (function->annex) + { + lf_indent (file, +2); + table_entry_print_cpp_line_nr (file, function->annex_line); + lf_print__c_code (file, function->annex); + lf_indent (file, -2); + } + lf_printf (file, "}\n"); + lf_print__internal_reference (file); + lf_printf (file, "\n"); +} + +void +gen_model_c (insn_table *table, lf *file) +{ + insn *insn_ptr; + model *model_ptr; + char *name; + int model_create_p = 0; + int model_init_p = 0; + int model_halt_p = 0; + int model_mon_info_p = 0; + int model_mon_info_free_p = 0; + + lf_printf (file, "\n"); + lf_printf (file, "#include \"cpu.h\"\n"); + lf_printf (file, "#include \"mon.h\"\n"); + lf_printf (file, "\n"); + lf_printf (file, "#ifdef HAVE_STDLIB_H\n"); + lf_printf (file, "#include \n"); + lf_printf (file, "#endif\n"); + lf_printf (file, "\n"); + + for (insn_ptr = model_data; insn_ptr; insn_ptr = insn_ptr->next) + { + model_c_or_h_data (table, file, insn_ptr->file_entry); + } + + for (insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next) + { + model_c_or_h_function (table, file, insn_ptr->file_entry, + "/*h*/STATIC"); + } + + for (insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) + { + model_c_or_h_function (table, file, insn_ptr->file_entry, + "STATIC_INLINE_MODEL"); + } + + for (insn_ptr = model_static; insn_ptr; insn_ptr = insn_ptr->next) + { + model_c_function (table, file, insn_ptr->file_entry, "/*c*/STATIC"); + } + + for (insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) + { + model_c_function (table, file, insn_ptr->file_entry, + "STATIC_INLINE_MODEL"); + } + + for (insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) + { + model_c_function (table, file, insn_ptr->file_entry, "INLINE_MODEL"); + name = insn_ptr->file_entry->fields[function_name]; + if (strcmp (name, "model_create") == 0) + model_create_p = 1; + else if (strcmp (name, "model_init") == 0) + model_init_p = 1; + else if (strcmp (name, "model_halt") == 0) + model_halt_p = 1; + else if (strcmp (name, "model_mon_info") == 0) + model_mon_info_p = 1; + else if (strcmp (name, "model_mon_info_free") == 0) + model_mon_info_free_p = 1; + } + + if (!model_create_p) + { + lf_print_function_type (file, "model_data *", "INLINE_MODEL", "\n"); + lf_printf (file, "model_create(sim_cpu *cpu)\n"); + lf_printf (file, "{\n"); + lf_printf (file, " return (model_data *)0;\n"); + lf_printf (file, "}\n"); + lf_printf (file, "\n"); + } + + if (!model_init_p) + { + lf_print_function_type (file, "void", "INLINE_MODEL", "\n"); + lf_printf (file, "model_init(model_data *model_ptr)\n"); + lf_printf (file, "{\n"); + lf_printf (file, "}\n"); + lf_printf (file, "\n"); + } + + if (!model_halt_p) + { + lf_print_function_type (file, "void", "INLINE_MODEL", "\n"); + lf_printf (file, "model_halt(model_data *model_ptr)\n"); + lf_printf (file, "{\n"); + lf_printf (file, "}\n"); + lf_printf (file, "\n"); + } + + if (!model_mon_info_p) + { + lf_print_function_type (file, "model_print *", "INLINE_MODEL", "\n"); + lf_printf (file, "model_mon_info(model_data *model_ptr)\n"); + lf_printf (file, "{\n"); + lf_printf (file, " return (model_print *)0;\n"); + lf_printf (file, "}\n"); + lf_printf (file, "\n"); + } + + if (!model_mon_info_free_p) + { + lf_print_function_type (file, "void", "INLINE_MODEL", "\n"); + lf_printf (file, "model_mon_info_free(model_data *model_ptr,\n"); + lf_printf (file, " model_print *info_ptr)\n"); + lf_printf (file, "{\n"); + lf_printf (file, "}\n"); + lf_printf (file, "\n"); + } + + lf_printf (file, "/* Insn functional unit info */\n"); + for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) + { + model_c_passed_data data; + + lf_printf (file, "static const model_time model_time_%s[] = {\n", + model_ptr->name); + data.file = file; + data.model_ptr = model_ptr; + insn_table_traverse_insn (table, NULL, (void *) &data, model_c_insn); + + lf_printf (file, "};\n"); + lf_printf (file, "\n"); + lf_printf (file, "\f\n"); + } + + lf_printf (file, "#ifndef _INLINE_C_\n"); + lf_printf (file, + "const model_time *const model_time_mapping[ (int)nr_models ] = {\n"); + lf_printf (file, " (const model_time *const)0,\n"); + for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) + { + lf_printf (file, " model_time_%s,\n", model_ptr->name); + } + lf_printf (file, "};\n"); + lf_printf (file, "#endif\n"); + lf_printf (file, "\n"); + + lf_printf (file, "\f\n"); + lf_printf (file, "/* map model enumeration into printable string */\n"); + lf_printf (file, "#ifndef _INLINE_C_\n"); + lf_printf (file, "const char *model_name[ (int)nr_models ] = {\n"); + lf_printf (file, " \"NONE\",\n"); + for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) + { + lf_printf (file, " \"%s\",\n", model_ptr->printable_name); + } + lf_printf (file, "};\n"); + lf_printf (file, "#endif\n"); + lf_printf (file, "\n"); + + lf_print_function_type (file, "void", "INLINE_MODEL", "\n"); + lf_printf (file, "model_set(const char *name)\n"); + lf_printf (file, "{\n"); + if (models) + { + lf_printf (file, " model_enum model;\n"); + lf_printf (file, + " for(model = MODEL_%s; model < nr_models; model++) {\n", + models->name); + lf_printf (file, " if(strcmp(name, model_name[model]) == 0) {\n"); + lf_printf (file, " current_model = model;\n"); + lf_printf (file, " return;\n"); + lf_printf (file, " }\n"); + lf_printf (file, " }\n"); + lf_printf (file, "\n"); + lf_printf (file, + " error(\"Unknown model '%%s', Models which are known are:%%s\n\",\n"); + lf_printf (file, " name,\n"); + lf_printf (file, " \""); + for (model_ptr = models; model_ptr; model_ptr = model_ptr->next) + { + lf_printf (file, "\\n\\t%s", model_ptr->printable_name); + } + lf_printf (file, "\");\n"); + } + else + { + lf_printf (file, " error(\"No models are currently known about\");\n"); + } + + lf_printf (file, "}\n"); +} + +#endif + + + +void +gen_model_h (lf *file, insn_table *table) +{ + lf_print__this_file_is_empty (file, "suffering bit rot"); +} + + +void +gen_model_c (lf *file, insn_table *table) +{ + lf_print__this_file_is_empty (file, "suffering bit rot"); +}
gen-model.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen-itable.c =================================================================== --- gen-itable.c (nonexistent) +++ gen-itable.c (revision 841) @@ -0,0 +1,303 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + + +#include "misc.h" +#include "lf.h" +#include "table.h" +#include "filter.h" +#include "igen.h" + +#include "ld-insn.h" +#include "ld-decode.h" + +#include "gen.h" + +#include "gen-itable.h" + +#ifndef NULL +#define NULL 0 +#endif + + + +typedef struct _itable_info +{ + int sizeof_form; + int sizeof_name; + int sizeof_file; +} +itable_info; + + +static void +itable_h_insn (lf *file, + insn_table *entry, insn_entry * instruction, void *data) +{ + int len; + itable_info *info = data; + lf_print__line_ref (file, instruction->line); + lf_printf (file, " "); + print_function_name (file, + instruction->name, + instruction->format_name, + NULL, NULL, function_name_prefix_itable); + lf_printf (file, ",\n"); + /* update summary info */ + len = strlen (instruction->format_name); + if (info->sizeof_form <= len) + info->sizeof_form = len + 1; + len = strlen (instruction->name); + if (info->sizeof_name <= len) + info->sizeof_name = len + 1; + len = strlen (filter_filename (instruction->line->file_name)); + if (info->sizeof_file <= len) + info->sizeof_file = len + 1; +} + + +/* print the list of all the different options */ + +static void +itable_print_enum (lf *file, filter *set, char *name) +{ + char *elem; + lf_printf (file, "typedef enum {\n"); + lf_indent (file, +2); + for (elem = filter_next (set, ""); + elem != NULL; elem = filter_next (set, elem)) + { + lf_printf (file, "%sitable_%s_%s,\n", + options.module.itable.prefix.l, name, elem); + if (strlen (options.module.itable.prefix.l) > 0) + { + lf_indent_suppress (file); + lf_printf (file, "#define itable_%s_%s %sitable_%s_%s\n", + name, elem, options.module.itable.prefix.l, name, elem); + } + } + lf_printf (file, "nr_%sitable_%ss,\n", options.module.itable.prefix.l, + name); + + lf_indent (file, -2); + lf_printf (file, "} %sitable_%ss;\n", options.module.itable.prefix.l, name); + if (strlen (options.module.itable.prefix.l) > 0) + { + lf_indent_suppress (file); + lf_printf (file, "#define itable_%ss %sitable_%ss\n", + name, options.module.itable.prefix.l, name); + lf_indent_suppress (file); + lf_printf (file, "#define nr_itable_%ss nr_%sitable_%ss\n", + name, options.module.itable.prefix.l, name); + } +} + +/* print an array of the option names as strings */ + +static void +itable_print_names (lf *file, filter *set, char *name) +{ + char *elem; + lf_printf (file, "const char *%sitable_%s_names[nr_%sitable_%ss + 1] = {\n", + options.module.itable.prefix.l, name, + options.module.itable.prefix.l, name); + lf_indent (file, +2); + for (elem = filter_next (set, ""); + elem != NULL; elem = filter_next (set, elem)) + { + lf_printf (file, "\"%s\",\n", elem); + } + lf_printf (file, "0,\n"); + lf_indent (file, -2); + lf_printf (file, "};\n"); +} + +extern void +gen_itable_h (lf *file, insn_table *isa) +{ + itable_info *info = ZALLOC (itable_info); + + /* output an enumerated type for each instruction */ + lf_printf (file, "typedef enum {\n"); + insn_table_traverse_insn (file, isa, itable_h_insn, info); + lf_printf (file, " nr_%sitable_entries,\n", + options.module.itable.prefix.l); + lf_printf (file, "} %sitable_index;\n", options.module.itable.prefix.l); + lf_printf (file, "\n"); + + /* output an enumeration type for each flag */ + itable_print_enum (file, isa->flags, "flag"); + lf_printf (file, "extern const char *%sitable_flag_names[];\n", + options.module.itable.prefix.l); + lf_printf (file, "\n"); + + /* output an enumeration of all the possible options */ + itable_print_enum (file, isa->options, "option"); + lf_printf (file, "extern const char *%sitable_option_names[];\n", + options.module.itable.prefix.l); + lf_printf (file, "\n"); + + /* output an enumeration of all the processor models */ + itable_print_enum (file, isa->model->processors, "processor"); + lf_printf (file, "extern const char *%sitable_processor_names[];\n", + options.module.itable.prefix.l); + lf_printf (file, "\n"); + + /* output the table that contains the actual instruction info */ + lf_printf (file, "typedef struct _%sitable_instruction_info {\n", + options.module.itable.prefix.l); + lf_printf (file, " %sitable_index nr;\n", options.module.itable.prefix.l); + lf_printf (file, " char *format;\n"); + lf_printf (file, " char *form;\n"); + lf_printf (file, " char *flags;\n"); + + /* nr_itable_* may be zero, so we add 1 to avoid an + illegal zero-sized array. */ + lf_printf (file, " char flag[nr_%sitable_flags + 1];\n", + options.module.itable.prefix.l); + lf_printf (file, " char *options;\n"); + lf_printf (file, " char option[nr_%sitable_options + 1];\n", + options.module.itable.prefix.l); + lf_printf (file, " char *processors;\n"); + lf_printf (file, " char processor[nr_%sitable_processors + 1];\n", + options.module.itable.prefix.l); + lf_printf (file, " char *name;\n"); + lf_printf (file, " char *file;\n"); + lf_printf (file, " int line_nr;\n"); + lf_printf (file, "} %sitable_info;\n", options.module.itable.prefix.l); + lf_printf (file, "\n"); + lf_printf (file, "extern %sitable_info %sitable[nr_%sitable_entries];\n", + options.module.itable.prefix.l, options.module.itable.prefix.l, + options.module.itable.prefix.l); + if (strlen (options.module.itable.prefix.l) > 0) + { + lf_indent_suppress (file); + lf_printf (file, "#define itable %sitable\n", + options.module.itable.prefix.l); + } + lf_printf (file, "\n"); + + /* output an enum defining the max size of various itable members */ + lf_printf (file, "enum {\n"); + lf_printf (file, " sizeof_%sitable_form = %d,\n", + options.module.itable.prefix.l, info->sizeof_form); + lf_printf (file, " sizeof_%sitable_name = %d,\n", + options.module.itable.prefix.l, info->sizeof_name); + lf_printf (file, " sizeof_%sitable_file = %d,\n", + options.module.itable.prefix.l, info->sizeof_file); + lf_printf (file, "};\n"); +} + + +/****************************************************************/ + +static void +itable_print_set (lf *file, filter *set, filter *members) +{ + char *elem; + lf_printf (file, "\""); + elem = filter_next (members, ""); + if (elem != NULL) + { + while (1) + { + lf_printf (file, "%s", elem); + elem = filter_next (members, elem); + if (elem == NULL) + break; + lf_printf (file, ","); + } + } + lf_printf (file, "\",\n"); + + lf_printf (file, "{"); + for (elem = filter_next (set, ""); + elem != NULL; elem = filter_next (set, elem)) + { + if (filter_is_member (members, elem)) + { + lf_printf (file, " 1,"); + } + else + { + lf_printf (file, " 0,"); + } + + } + /* always print a dummy element, to avoid empty initializers. */ + lf_printf (file, " 99 },\n"); +} + + +static void +itable_c_insn (lf *file, + insn_table *isa, insn_entry * instruction, void *data) +{ + lf_printf (file, "{ "); + lf_indent (file, +2); + print_function_name (file, + instruction->name, + instruction->format_name, + NULL, NULL, function_name_prefix_itable); + lf_printf (file, ",\n"); + lf_printf (file, "\""); + print_insn_words (file, instruction); + lf_printf (file, "\",\n"); + lf_printf (file, "\"%s\",\n", instruction->format_name); + + itable_print_set (file, isa->flags, instruction->flags); + itable_print_set (file, isa->options, instruction->options); + itable_print_set (file, isa->model->processors, instruction->processors); + + lf_printf (file, "\"%s\",\n", instruction->name); + lf_printf (file, "\"%s\",\n", + filter_filename (instruction->line->file_name)); + lf_printf (file, "%d,\n", instruction->line->line_nr); + lf_printf (file, "},\n"); + lf_indent (file, -2); +} + + +extern void +gen_itable_c (lf *file, insn_table *isa) +{ + /* leader */ + lf_printf (file, "#include \"%sitable.h\"\n", + options.module.itable.prefix.l); + lf_printf (file, "\n"); + + /* FIXME - output model data??? */ + /* FIXME - output assembler data??? */ + + /* output the flag, option and processor name tables */ + itable_print_names (file, isa->flags, "flag"); + itable_print_names (file, isa->options, "option"); + itable_print_names (file, isa->model->processors, "processor"); + + /* output the table that contains the actual instruction info */ + lf_printf (file, "%sitable_info %sitable[nr_%sitable_entries] = {\n", + options.module.itable.prefix.l, + options.module.itable.prefix.l, options.module.itable.prefix.l); + insn_table_traverse_insn (file, isa, itable_c_insn, NULL); + + lf_printf (file, "};\n"); +}
gen-itable.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: ld-insn.h =================================================================== --- ld-insn.h (nonexistent) +++ ld-insn.h (revision 841) @@ -0,0 +1,706 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + + +typedef unsigned64 insn_uint; + + +/* Common among most entries: + + All non instruction records have the format: + + <...> ::= + ":" + ":" + ":" + ":" ... + + */ + +enum +{ + record_type_field = 1, + old_record_type_field = 2, + record_filter_flags_field = 2, + record_filter_models_field = 3, +}; + + +/* Include: + + Include the specified file. + + ::= + ":" "include" + ":" + ":" + ":" + + ; + + */ + +enum +{ + include_filename_field = 4, + nr_include_fields, +}; + + + +/* Options: + + Valid options are: hi-bit-nr (default 0), insn-bit-size (default + 32), insn-specifying-widths (default true), multi-sim (default false). + +
ld-insn.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: compare_igen_models =================================================================== --- compare_igen_models (nonexistent) +++ compare_igen_models (revision 841) @@ -0,0 +1,112 @@ +#!/bin/sh + +# Script to compare functions and instructions used by different igen models. +# Copyright (C) 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# Contributed by Chris Demetriou of Broadcom Corporation (SiByte). +# +# This file is part of GDB, the GNU debugger. +# +# 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 . + +# This is a simple-minded script to compare the functions and instructions +# listed for two different models in one or more .igen files. +# +# It was intended to be useful to help factor models into common subsets. +# +# Things to note: +# +# * igen include directives are not processed! +# +# * functions and instructions with multiple definitions (e.g., based +# on model names) are treated as being different. In other words, +# if two models have different functions named 'foo', this +# script will say that one has one of the function definitions, and +# the other has the other. + +if [ "$#" -lt 2 ]; then + echo "usage: $0 model1 model2 [file ...]" 1>&2 + exit 1 +fi +model1="$1" +model2="$2" +shift; shift + +gawk -v model1="$model1" -v model2="$model2" -F: -- ' +BEGIN { + thang_count = 0 +} +function thang_has_model(t, m) { +# printf("thang_has_model(%s, %s) (@ %s:%d)\n", t, m, +# thangs[t,"file"], thangs[t,"line"]); + if (thangs[t,"nmodels"] == 0) return 1; + + for (j = 0; j < thangs[t,"nmodels"]; j++) { +# printf("\tmodel \"%s\"\n", thangs[t,"models",j]); + if (thangs[t,"models",j] == m) return 1; + } +# printf("\t-> 0\n"); + return 0 +} +function compare_models(m1, m2) { +# printf("compare_models(%s, %s)\n", m1, m2); + seen_any=0 + for (i = 0; i < thang_count; i++) { + if (thang_has_model(i, m1) && !thang_has_model(i, m2)) { + if (!seen_any) { + printf("Things in %s but not in %s:\n", m1, m2); + seen_any = 1 + } + printf("%s:%d: %s\n", thangs[i,"file"], + thangs[i,"line"], thangs[i,"contents"]); + } + } +} +$0 ~ /^:/ && $2 == "model" { + # ignore. + # print "model " $0 +} +($0 ~ /^:/ && $2 == "function") || \ +($0 ~ /^:/ && $2 == "internal") || \ +($0 ~ /^[0-9]/) { + # a function, internal, or instruction. + + current_thang = thang_count + thang_count++ + + thangs[current_thang,"file"] = FILENAME + thangs[current_thang,"line"] = NR + thangs[current_thang,"contents"] = $0 + thangs[current_thang,"nmodels"] = 0 + + if ($0 ~ /^:/) { + thangs[current_thang,"type"] = $2 + } else { + thangs[current_thang,"type"] = "instruction" + } +} +$0 ~ /^\*/ { + split(substr($1, 2), tmp_models, /,/) + for (key in tmp_models) { + current_model = thangs[current_thang,"nmodels"] + thangs[current_thang,"nmodels"]++ + thangs[current_thang,"models",current_model] = tmp_models[key] + } +} +END { + compare_models(model1, model2) + if (seen_any) printf("\n"); + compare_models(model2, model1) +}' "$@" + +exit "$?"
compare_igen_models Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: gen-model.h =================================================================== --- gen-model.h (nonexistent) +++ gen-model.h (revision 841) @@ -0,0 +1,26 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + + +extern void gen_model_h (lf *file, insn_table *isa); + +extern void gen_model_c (lf *file, insn_table *isa);
gen-model.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen-itable.h =================================================================== --- gen-itable.h (nonexistent) +++ gen-itable.h (revision 841) @@ -0,0 +1,28 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + + +/* Output a table of all the instructions */ + +extern void gen_itable_h (lf *file, insn_table *table); + +extern void gen_itable_c (lf *file, insn_table *table);
gen-itable.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen-engine.c =================================================================== --- gen-engine.c (nonexistent) +++ gen-engine.c (revision 841) @@ -0,0 +1,766 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + +#include "misc.h" +#include "lf.h" +#include "table.h" +#include "filter.h" + +#include "igen.h" + +#include "ld-insn.h" +#include "ld-decode.h" + +#include "gen.h" + +#include "gen-idecode.h" +#include "gen-engine.h" +#include "gen-icache.h" +#include "gen-semantics.h" + + +static void +print_engine_issue_prefix_hook (lf *file) +{ + lf_printf (file, "\n"); + lf_indent_suppress (file); + lf_printf (file, "#if defined (ENGINE_ISSUE_PREFIX_HOOK)\n"); + lf_printf (file, "ENGINE_ISSUE_PREFIX_HOOK();\n"); + lf_indent_suppress (file); + lf_printf (file, "#endif\n"); + lf_printf (file, "\n"); +} + +static void +print_engine_issue_postfix_hook (lf *file) +{ + lf_printf (file, "\n"); + lf_indent_suppress (file); + lf_printf (file, "#if defined (ENGINE_ISSUE_POSTFIX_HOOK)\n"); + lf_printf (file, "ENGINE_ISSUE_POSTFIX_HOOK();\n"); + lf_indent_suppress (file); + lf_printf (file, "#endif\n"); + lf_printf (file, "\n"); +} + + +static void +print_run_body (lf *file, gen_entry *table) +{ + /* Output the function to execute real code: + + Unfortunatly, there are multiple cases to consider vis: + + X + + Consequently this function is written in multiple different ways */ + + lf_printf (file, "{\n"); + lf_indent (file, +2); + if (!options.gen.smp) + { + lf_printf (file, "%sinstruction_address cia;\n", + options.module.global.prefix.l); + } + lf_printf (file, "int current_cpu = next_cpu_nr;\n"); + + if (options.gen.icache) + { + lf_printf (file, "/* flush the icache of a possible break insn */\n"); + lf_printf (file, "{\n"); + lf_printf (file, " int cpu_nr;\n"); + lf_printf (file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n"); + lf_printf (file, " cpu_flush_icache (STATE_CPU (sd, cpu_nr));\n"); + lf_printf (file, "}\n"); + } + + if (!options.gen.smp) + { + + lf_putstr (file, "\ +/* CASE 1: NO SMP (with or with out instruction cache).\n\ +\n\ +In this case, we can take advantage of the fact that the current\n\ +instruction address (CIA) does not need to be read from / written to\n\ +the CPU object after the execution of an instruction.\n\ +\n\ +Instead, CIA is only saved when the main loop exits. This occures\n\ +when either sim_engine_halt or sim_engine_restart is called. Both of\n\ +these functions save the current instruction address before halting /\n\ +restarting the simulator.\n\ +\n\ +As a variation, there may also be support for an instruction cracking\n\ +cache. */\n\ +\n\ +"); + + lf_putstr (file, "\n"); + lf_putstr (file, "/* prime the main loop */\n"); + lf_putstr (file, "SIM_ASSERT (current_cpu == 0);\n"); + lf_putstr (file, "SIM_ASSERT (nr_cpus == 1);\n"); + lf_putstr (file, "cia = CIA_GET (CPU);\n"); + + lf_putstr (file, "\n"); + lf_putstr (file, "while (1)\n"); + lf_putstr (file, " {\n"); + lf_indent (file, +4); + + lf_printf (file, "%sinstruction_address nia;\n", + options.module.global.prefix.l); + + lf_printf (file, "\n"); + if (!options.gen.icache) + { + lf_printf (file, + "%sinstruction_word instruction_0 = IMEM%d (cia);\n", + options.module.global.prefix.l, options.insn_bit_size); + print_engine_issue_prefix_hook (file); + print_idecode_body (file, table, "nia = "); + print_engine_issue_postfix_hook (file); + } + else + { + lf_putstr (file, "idecode_cache *cache_entry =\n"); + lf_putstr (file, " cpu_icache_entry (cpu, cia);\n"); + lf_putstr (file, "if (cache_entry->address == cia)\n"); + lf_putstr (file, " {\n"); + lf_indent (file, -4); + lf_putstr (file, "/* cache hit */\n"); + lf_putstr (file, + "idecode_semantic *const semantic = cache_entry->semantic;\n"); + lf_putstr (file, "cia = semantic (cpu, cache_entry, cia);\n"); + /* tail */ + lf_indent (file, -4); + lf_putstr (file, " }\n"); + lf_putstr (file, "else\n"); + lf_putstr (file, " {\n"); + lf_indent (file, +4); + lf_putstr (file, "/* cache miss */\n"); + if (!options.gen.semantic_icache) + { + lf_putstr (file, "idecode_semantic *semantic;\n"); + } + lf_printf (file, "instruction_word instruction = IMEM%d (cia);\n", + options.insn_bit_size); + lf_putstr (file, "if (WITH_MON != 0)\n"); + lf_putstr (file, + " mon_event (mon_event_icache_miss, cpu, cia);\n"); + if (options.gen.semantic_icache) + { + lf_putstr (file, "{\n"); + lf_indent (file, +2); + print_engine_issue_prefix_hook (file); + print_idecode_body (file, table, "nia ="); + print_engine_issue_postfix_hook (file); + lf_indent (file, -2); + lf_putstr (file, "}\n"); + } + else + { + print_engine_issue_prefix_hook (file); + print_idecode_body (file, table, "semantic ="); + lf_putstr (file, "nia = semantic (cpu, cache_entry, cia);\n"); + print_engine_issue_postfix_hook (file); + } + lf_indent (file, -4); + lf_putstr (file, " }\n"); + } + + /* update the cpu if necessary */ + switch (options.gen.nia) + { + case nia_is_cia_plus_one: + lf_printf (file, "\n"); + lf_printf (file, "/* Update the instruction address */\n"); + lf_printf (file, "cia = nia;\n"); + break; + case nia_is_void: + case nia_is_invalid: + ERROR ("engine gen when NIA complex"); + } + + /* events */ + lf_putstr (file, "\n"); + lf_putstr (file, "/* process any events */\n"); + lf_putstr (file, "if (sim_events_tick (sd))\n"); + lf_putstr (file, " {\n"); + lf_putstr (file, " CIA_SET (CPU, cia);\n"); + lf_putstr (file, " sim_events_process (sd);\n"); + lf_putstr (file, " cia = CIA_GET (CPU);\n"); + lf_putstr (file, " }\n"); + + lf_indent (file, -4); + lf_printf (file, " }\n"); + } + + if (options.gen.smp) + { + + lf_putstr (file, "\ +/* CASE 2: SMP (With or without ICACHE)\n\ +\n\ +The complexity here comes from needing to correctly halt the simulator\n\ +when it is aborted. For instance, if cpu0 requests a restart then\n\ +cpu1 will normally be the next cpu that is run. Cpu0 being restarted\n\ +after all the other CPU's and the event queue have been processed */\n\ +\n\ +"); + + lf_putstr (file, "\n"); + lf_printf (file, + "/* have ensured that the event queue is NOT next */\n"); + lf_printf (file, "SIM_ASSERT (current_cpu >= 0);\n"); + lf_printf (file, "SIM_ASSERT (current_cpu <= nr_cpus - 1);\n"); + lf_printf (file, "SIM_ASSERT (nr_cpus <= MAX_NR_PROCESSORS);\n"); + + lf_putstr (file, "\n"); + lf_putstr (file, "while (1)\n"); + lf_putstr (file, " {\n"); + lf_indent (file, +4); + lf_putstr (file, "sim_cpu *cpu = STATE_CPU (sd, current_cpu);\n"); + lf_putstr (file, "instruction_address cia = CIA_GET (cpu);\n"); + lf_putstr (file, "\n"); + + if (!options.gen.icache) + { + lf_printf (file, "instruction_word instruction_0 = IMEM%d (cia);\n", + options.insn_bit_size); + print_engine_issue_prefix_hook (file); + print_idecode_body (file, table, "cia ="); + lf_putstr (file, "CIA_SET (cpu, cia);\n"); + print_engine_issue_postfix_hook (file); + } + + if (options.gen.icache) + { + lf_putstr (file, "engine_cache *cache_entry =\n"); + lf_putstr (file, " cpu_icache_entry(processor, cia);\n"); + lf_putstr (file, "\n"); + lf_putstr (file, "if (cache_entry->address == cia) {\n"); + { + lf_indent (file, +2); + lf_putstr (file, "\n"); + lf_putstr (file, "/* cache hit */\n"); + lf_putstr (file, + "engine_semantic *semantic = cache_entry->semantic;\n"); + lf_putstr (file, + "cia = semantic(processor, cache_entry, cia);\n"); + /* tail */ + lf_putstr (file, "cpu_set_program_counter(processor, cia);\n"); + lf_putstr (file, "\n"); + lf_indent (file, -2); + } + lf_putstr (file, "}\n"); + lf_putstr (file, "else {\n"); + { + lf_indent (file, +2); + lf_putstr (file, "\n"); + lf_putstr (file, "/* cache miss */\n"); + if (!options.gen.semantic_icache) + { + lf_putstr (file, "engine_semantic *semantic;\n"); + } + lf_printf (file, "instruction_word instruction = IMEM%d (cia);\n", + options.insn_bit_size); + lf_putstr (file, "if (WITH_MON != 0)\n"); + lf_putstr (file, + " mon_event(mon_event_icache_miss, processors[current_cpu], cia);\n"); + if (options.gen.semantic_icache) + { + lf_putstr (file, "{\n"); + lf_indent (file, +2); + print_engine_issue_prefix_hook (file); + print_idecode_body (file, table, "cia ="); + print_engine_issue_postfix_hook (file); + lf_indent (file, -2); + lf_putstr (file, "}\n"); + } + else + { + print_engine_issue_prefix_hook (file); + print_idecode_body (file, table, "semantic = "); + lf_putstr (file, + "cia = semantic(processor, cache_entry, cia);\n"); + print_engine_issue_postfix_hook (file); + } + /* tail */ + lf_putstr (file, "cpu_set_program_counter(processor, cia);\n"); + lf_putstr (file, "\n"); + lf_indent (file, -2); + } + lf_putstr (file, "}\n"); + } + + lf_putstr (file, "\n"); + lf_putstr (file, "current_cpu += 1;\n"); + lf_putstr (file, "if (current_cpu == nr_cpus)\n"); + lf_putstr (file, " {\n"); + lf_putstr (file, " if (sim_events_tick (sd))\n"); + lf_putstr (file, " {\n"); + lf_putstr (file, " sim_events_process (sd);\n"); + lf_putstr (file, " }\n"); + lf_putstr (file, " current_cpu = 0;\n"); + lf_putstr (file, " }\n"); + + /* tail */ + lf_indent (file, -4); + lf_putstr (file, " }\n"); + } + + + lf_indent (file, -2); + lf_putstr (file, "}\n"); +} + + +/****************************************************************/ + +#if 0 +static void +print_jump (lf *file, int is_tail) +{ + if (!options.gen.smp) + { + lf_putstr (file, "if (event_queue_tick (sd))\n"); + lf_putstr (file, " {\n"); + lf_putstr (file, " CPU_CIA (processor) = nia;\n"); + lf_putstr (file, " sim_events_process (sd);\n"); + lf_putstr (file, " }\n"); + lf_putstr (file, "}\n"); + } + + if (options.gen.smp) + { + if (is_tail) + lf_putstr (file, "cpu_set_program_counter(processor, nia);\n"); + lf_putstr (file, "current_cpu += 1;\n"); + lf_putstr (file, "if (current_cpu >= nr_cpus)\n"); + lf_putstr (file, " {\n"); + lf_putstr (file, " if (sim_events_tick (sd))\n"); + lf_putstr (file, " {\n"); + lf_putstr (file, " sim_events_process (sd);\n"); + lf_putstr (file, " }\n"); + lf_putstr (file, " current_cpu = 0;\n"); + lf_putstr (file, " }\n"); + lf_putstr (file, "processor = processors[current_cpu];\n"); + lf_putstr (file, "nia = cpu_get_program_counter(processor);\n"); + } + + if (options.gen.icache) + { + lf_putstr (file, "cache_entry = cpu_icache_entry(processor, nia);\n"); + lf_putstr (file, "if (cache_entry->address == nia) {\n"); + lf_putstr (file, " /* cache hit */\n"); + lf_putstr (file, " goto *cache_entry->semantic;\n"); + lf_putstr (file, "}\n"); + if (is_tail) + { + lf_putstr (file, "goto cache_miss;\n"); + } + } + + if (!options.gen.icache && is_tail) + { + lf_printf (file, "goto engine;\n"); + } + +} +#endif + + +#if 0 +static void +print_jump_insn (lf *file, + insn_entry * instruction, + opcode_bits *expanded_bits, + opcode_field *opcodes, cache_entry *cache_rules) +{ + insn_opcodes opcode_path; + + memset (&opcode_path, 0, sizeof (opcode_path)); + opcode_path.opcode = opcodes; + + /* what we are for the moment */ + lf_printf (file, "\n"); + print_my_defines (file, + instruction->name, + instruction->format_name, expanded_bits); + + /* output the icache entry */ + if (options.gen.icache) + { + lf_printf (file, "\n"); + lf_indent (file, -1); + print_function_name (file, + instruction->name, + instruction->format_name, + NULL, expanded_bits, function_name_prefix_icache); + lf_printf (file, ":\n"); + lf_indent (file, +1); + lf_printf (file, "{\n"); + lf_indent (file, +2); + lf_putstr (file, "const unsigned_word cia = nia;\n"); + print_itrace (file, instruction, 1 /*putting-value-in-cache */ ); + print_idecode_validate (file, instruction, &opcode_path); + lf_printf (file, "\n"); + lf_printf (file, "{\n"); + lf_indent (file, +2); + print_icache_body (file, instruction, expanded_bits, cache_rules, 0, /*use_defines */ + put_values_in_icache); + lf_printf (file, "cache_entry->address = nia;\n"); + lf_printf (file, "cache_entry->semantic = &&"); + print_function_name (file, + instruction->name, + instruction->format_name, + NULL, + expanded_bits, function_name_prefix_semantics); + lf_printf (file, ";\n"); + if (options.gen.semantic_icache) + { + print_semantic_body (file, + instruction, expanded_bits, &opcode_path); + print_jump (file, 1 /*is-tail */ ); + } + else + { + lf_printf (file, "/* goto "); + print_function_name (file, + instruction->name, + instruction->format_name, + NULL, + expanded_bits, function_name_prefix_semantics); + lf_printf (file, "; */\n"); + } + lf_indent (file, -2); + lf_putstr (file, "}\n"); + lf_indent (file, -2); + lf_printf (file, "}\n"); + } + + /* print the semantics */ + lf_printf (file, "\n"); + lf_indent (file, -1); + print_function_name (file, + instruction->name, + instruction->format_name, + NULL, expanded_bits, function_name_prefix_semantics); + lf_printf (file, ":\n"); + lf_indent (file, +1); + lf_printf (file, "{\n"); + lf_indent (file, +2); + lf_putstr (file, "const unsigned_word cia = nia;\n"); + print_icache_body (file, + instruction, + expanded_bits, + cache_rules, + (options.gen.direct_access + ? define_variables + : declare_variables), + (options.gen.icache + ? get_values_from_icache : do_not_use_icache)); + print_semantic_body (file, instruction, expanded_bits, &opcode_path); + if (options.gen.direct_access) + print_icache_body (file, + instruction, + expanded_bits, + cache_rules, + undef_variables, + (options.gen.icache + ? get_values_from_icache : do_not_use_icache)); + print_jump (file, 1 /*is tail */ ); + lf_indent (file, -2); + lf_printf (file, "}\n"); +} +#endif + + +#if 0 +static void +print_jump_definition (lf *file, gen_entry *entry, int depth, void *data) +{ + cache_entry *cache_rules = (cache_entry *) data; + if (entry->opcode_rule->with_duplicates) + { + ASSERT (entry->nr_insns == 1 + && entry->opcode == NULL + && entry->parent != NULL && entry->parent->opcode != NULL); + ASSERT (entry->nr_insns == 1 + && entry->opcode == NULL + && entry->parent != NULL + && entry->parent->opcode != NULL + && entry->parent->opcode_rule != NULL); + print_jump_insn (file, + entry->insns->insn, + entry->expanded_bits, entry->opcode, cache_rules); + } + else + { + print_jump_insn (file, entry->insns->insn, NULL, NULL, cache_rules); + } +} +#endif + + +#if 0 +static void +print_jump_internal_function (lf *file, function_entry * function, void *data) +{ + if (function->is_internal) + { + lf_printf (file, "\n"); + lf_print__line_ref (file, function->line); + lf_indent (file, -1); + print_function_name (file, + function->name, + NULL, + NULL, + NULL, + (options.gen.icache + ? function_name_prefix_icache + : function_name_prefix_semantics)); + lf_printf (file, ":\n"); + lf_indent (file, +1); + lf_printf (file, "{\n"); + lf_indent (file, +2); + lf_printf (file, "const unsigned_word cia = nia;\n"); + table_print_code (file, function->code); + lf_print__internal_ref (file); + lf_printf (file, "error(\"Internal function must longjump\\n\");\n"); + lf_indent (file, -2); + lf_printf (file, "}\n"); + } +} +#endif + + +#if 0 +static void +print_jump_body (lf *file, + gen_entry *entry, insn_table *isa, cache_entry *cache_rules) +{ + lf_printf (file, "{\n"); + lf_indent (file, +2); + lf_putstr (file, "jmp_buf halt;\n"); + lf_putstr (file, "jmp_buf restart;\n"); + lf_putstr (file, "cpu *processor = NULL;\n"); + lf_putstr (file, "unsigned_word nia = -1;\n"); + lf_putstr (file, "instruction_word instruction = 0;\n"); + if (options.gen.icache) + { + lf_putstr (file, "engine_cache *cache_entry = NULL;\n"); + } + if (options.gen.smp) + { + lf_putstr (file, "int current_cpu = -1;\n"); + } + + /* all the switches and tables - they know about jumping */ + print_idecode_lookups (file, entry, cache_rules); + + /* start the simulation up */ + if (options.gen.icache) + { + lf_putstr (file, "\n"); + lf_putstr (file, "{\n"); + lf_putstr (file, " int cpu_nr;\n"); + lf_putstr (file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n"); + lf_putstr (file, " cpu_flush_icache(processors[cpu_nr]);\n"); + lf_putstr (file, "}\n"); + } + + lf_putstr (file, "\n"); + lf_putstr (file, "psim_set_halt_and_restart(system, &halt, &restart);\n"); + + lf_putstr (file, "\n"); + lf_putstr (file, "if (setjmp(halt))\n"); + lf_putstr (file, " return;\n"); + + lf_putstr (file, "\n"); + lf_putstr (file, "setjmp(restart);\n"); + + lf_putstr (file, "\n"); + if (!options.gen.smp) + { + lf_putstr (file, "processor = processors[0];\n"); + lf_putstr (file, "nia = cpu_get_program_counter(processor);\n"); + } + else + { + lf_putstr (file, "current_cpu = psim_last_cpu(system);\n"); + } + + if (!options.gen.icache) + { + lf_printf (file, "\n"); + lf_indent (file, -1); + lf_printf (file, "engine:\n"); + lf_indent (file, +1); + } + + print_jump (file, 0 /*is_tail */ ); + + if (options.gen.icache) + { + lf_indent (file, -1); + lf_printf (file, "cache_miss:\n"); + lf_indent (file, +1); + } + + print_engine_issue_prefix_hook (file); + lf_putstr (file, "instruction\n"); + lf_putstr (file, + " = vm_instruction_map_read(cpu_instruction_map(processor),\n"); + lf_putstr (file, " processor, nia);\n"); + print_engine_issue_prefix_hook (file); + print_idecode_body (file, entry, "/*IGORE*/"); + print_engine_issue_postfix_hook (file); + + /* print out a table of all the internals functions */ + function_entry_traverse (file, isa->functions, + print_jump_internal_function, NULL); + + /* print out a table of all the instructions */ + ERROR ("Use the list of semantic functions, not travere_tree"); + gen_entry_traverse_tree (file, entry, 1, NULL, /* start */ + print_jump_definition, /* leaf */ + NULL, /* end */ + cache_rules); + lf_indent (file, -2); + lf_printf (file, "}\n"); +} +#endif + + +/****************************************************************/ + + +void +print_engine_run_function_header (lf *file, + char *processor, + function_decl_type decl_type) +{ + int indent; + lf_printf (file, "\n"); + switch (decl_type) + { + case is_function_declaration: + lf_print__function_type (file, "void", "INLINE_ENGINE", "\n"); + break; + case is_function_definition: + lf_print__function_type (file, "void", "INLINE_ENGINE", " "); + break; + case is_function_variable: + lf_printf (file, "void (*"); + break; + } + indent = print_function_name (file, "run", NULL, /* format name */ + processor, NULL, /* expanded bits */ + function_name_prefix_engine); + switch (decl_type) + { + case is_function_definition: + lf_putstr (file, "\n("); + indent = 1; + break; + case is_function_declaration: + indent += lf_printf (file, " ("); + break; + case is_function_variable: + lf_putstr (file, ")\n("); + indent = 1; + break; + } + lf_indent (file, +indent); + lf_printf (file, "SIM_DESC sd,\n"); + lf_printf (file, "int next_cpu_nr,\n"); + lf_printf (file, "int nr_cpus,\n"); + lf_printf (file, "int siggnal)"); + lf_indent (file, -indent); + switch (decl_type) + { + case is_function_definition: + lf_putstr (file, "\n"); + break; + case is_function_variable: + case is_function_declaration: + lf_putstr (file, ";\n"); + break; + } +} + + +void +gen_engine_h (lf *file, + gen_table *gen, insn_table *isa, cache_entry *cache_rules) +{ + gen_list *entry; + for (entry = gen->tables; entry != NULL; entry = entry->next) + { + print_engine_run_function_header (file, + (options.gen.multi_sim + ? entry->model->name + : NULL), is_function_declaration); + } +} + + +void +gen_engine_c (lf *file, + gen_table *gen, insn_table *isa, cache_entry *cache_rules) +{ + gen_list *entry; + /* the intro */ + print_includes (file); + print_include_inline (file, options.module.semantics); + print_include (file, options.module.engine); + lf_printf (file, "\n"); + lf_printf (file, "#include \"sim-assert.h\"\n"); + lf_printf (file, "\n"); + print_idecode_globals (file); + lf_printf (file, "\n"); + + for (entry = gen->tables; entry != NULL; entry = entry->next) + { + switch (options.gen.code) + { + case generate_calls: + print_idecode_lookups (file, entry->table, cache_rules); + + /* output the main engine routine */ + print_engine_run_function_header (file, + (options.gen.multi_sim + ? entry->model->name + : NULL), is_function_definition); + print_run_body (file, entry->table); + break; + + case generate_jumps: + ERROR ("Jumps currently unimplemented"); +#if 0 + print_engine_run_function_header (file, + entry->processor, + is_function_definition); + print_jump_body (file, entry->table, isa, cache_rules); +#endif + break; + } + } +}
gen-engine.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: ld-decode.c =================================================================== --- ld-decode.c (nonexistent) +++ ld-decode.c (revision 841) @@ -0,0 +1,409 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +/* load the opcode stat structure */ + +#include "misc.h" +#include "lf.h" +#include "table.h" +#include "filter.h" + +#include "igen.h" + +#include "ld-decode.h" + +#ifndef NULL +#define NULL 0 +#endif + + +static const name_map decode_type_map[] = { + {"normal", normal_decode_rule}, + {"boolean", boolean_rule}, + {NULL, normal_decode_rule}, +}; + +static const name_map decode_gen_map[] = { + {"array", array_gen}, + {"switch", switch_gen}, + {"padded-switch", padded_switch_gen}, + {"goto-switch", goto_switch_gen}, + {NULL, -1}, +}; + +static const name_map decode_reserved_map[] = { + {"zero-reserved", 1}, + {NULL, 0}, +}; + +static const name_map decode_duplicates_map[] = { + {"duplicate", 1}, + {NULL, 0}, +}; + +static const name_map decode_combine_map[] = { + {"combine", 1}, + {NULL, 0}, +}; + +static const name_map decode_search_map[] = { + {"constants", decode_find_constants}, + {"mixed", decode_find_mixed}, + {"strings", decode_find_strings}, + {NULL, decode_find_mixed}, +}; + + +static void +set_bits (int bit[max_insn_bit_size], unsigned64 value) +{ + int bit_nr; + for (bit_nr = 0; bit_nr < max_insn_bit_size; bit_nr++) + { + if (bit_nr < options.insn_bit_size) + bit[bit_nr] = (value >> (options.insn_bit_size - bit_nr - 1)) & 1; + else + bit[bit_nr] = 0; + } +} + +decode_table * +load_decode_table (char *file_name) +{ + table *file = table_open (file_name); + table_entry *entry; + decode_table *table = NULL; + decode_table **curr_rule = &table; + while ((entry = table_read (file)) != NULL) + { + char *decode_options = entry->field[decode_options_field]; + decode_table *new_rule = ZALLOC (decode_table); + if (entry->nr_fields < min_nr_decode_fields) + error (entry->line, "Missing decode table fields\n"); + new_rule->line = entry->line; + + /* the options field */ + new_rule->type = name2i (decode_options, decode_type_map); + if (options.decode.overriding_gen != NULL) + new_rule->gen = + name2i (options.decode.overriding_gen, decode_gen_map); + else + new_rule->gen = name2i (decode_options, decode_gen_map); + if (new_rule->gen == padded_switch_gen && options.decode.switch_as_goto) + new_rule->gen = goto_switch_gen; + if (options.decode.zero_reserved) + new_rule->with_zero_reserved = 1; + else + new_rule->with_zero_reserved = + name2i (decode_options, decode_reserved_map); + if (options.decode.duplicate) + new_rule->with_duplicates = 1; + else + new_rule->with_duplicates = + name2i (decode_options, decode_duplicates_map); + if (options.decode.combine) + new_rule->with_combine = 1; + else + new_rule->with_combine = name2i (decode_options, decode_combine_map); + if (new_rule->type == boolean_rule) + { + char *chp = decode_options; + while (*chp != '\0') + { + if (isdigit (*chp)) + { + new_rule->constant = a2i (chp); + break; + } + chp = skip_to_separator (chp, ","); + chp = skip_spaces (chp); + } + } + + /* First and last */ + if (entry->nr_fields > decode_first_field + && strlen (entry->field[decode_first_field]) > 0) + { + new_rule->first = target_a2i (options.hi_bit_nr, + entry->field[decode_first_field]); + if (new_rule->first < 0 || new_rule->first >= options.insn_bit_size) + error (new_rule->line, "First field out of range\n"); + } + else + new_rule->first = 0; + if (entry->nr_fields > decode_last_field + && strlen (entry->field[decode_last_field]) > 0) + { + new_rule->last = target_a2i (options.hi_bit_nr, + entry->field[decode_last_field]); + if (new_rule->last < 0 || new_rule->last >= options.insn_bit_size) + error (new_rule->line, "Last field out of range\n"); + } + else + new_rule->last = options.insn_bit_size - 1; + if (new_rule->first > new_rule->last) + error (new_rule->line, "First must preceed last\n"); + + /* force first/last, with default values based on first/last */ + if (entry->nr_fields > decode_force_first_field + && strlen (entry->field[decode_force_first_field]) > 0) + { + new_rule->force_first = target_a2i (options.hi_bit_nr, + entry-> + field + [decode_force_first_field]); + if (new_rule->force_first < new_rule->first + || new_rule->force_first > new_rule->last + 1) + error (new_rule->line, "Force first out of range\n"); + } + else + new_rule->force_first = new_rule->last + 1; + if (entry->nr_fields > decode_force_last_field + && strlen (entry->field[decode_force_last_field]) > 0) + { + new_rule->force_last = target_a2i (options.hi_bit_nr, + entry-> + field[decode_force_last_field]); + if (new_rule->force_last > new_rule->last + || new_rule->force_last < new_rule->first - 1) + error (new_rule->line, "Force-last out of range\n"); + } + else + new_rule->force_last = new_rule->first - 1; + + /* fields to be treated as constant */ + if (entry->nr_fields > decode_constant_field_names_field) + filter_parse (&new_rule->constant_field_names, + entry->field[decode_constant_field_names_field]); + + /* applicable word nr */ + if (entry->nr_fields > decode_word_nr_field) + new_rule->word_nr = a2i (entry->field[decode_word_nr_field]); + + /* required instruction format names */ + if (entry->nr_fields > decode_format_names_field) + filter_parse (&new_rule->format_names, + entry->field[decode_format_names_field]); + + /* required processor models */ + if (entry->nr_fields > decode_model_names_field) + filter_parse (&new_rule->model_names, + entry->field[decode_model_names_field]); + + /* required paths */ + if (entry->nr_fields > decode_paths_field + && strlen (entry->field[decode_paths_field]) > 0) + { + decode_path_list **last = &new_rule->paths; + char *chp = entry->field[decode_paths_field]; + do + { + (*last) = ZALLOC (decode_path_list); + /* extra root/zero entry */ + (*last)->path = ZALLOC (decode_path); + do + { + decode_path *entry = ZALLOC (decode_path); + entry->opcode_nr = a2i (chp); + entry->parent = (*last)->path; + (*last)->path = entry; + chp = skip_digits (chp); + chp = skip_spaces (chp); + } + while (*chp == '.'); + last = &(*last)->next; + } + while (*chp == ','); + if (*chp != '\0') + error (entry->line, "Invalid path field\n"); + } + + /* collect up the list of optional special conditions applicable + to the rule */ + { + int field_nr = nr_decode_fields; + while (entry->nr_fields > field_nr) + { + decode_cond *cond = ZALLOC (decode_cond); + decode_cond **last; + if (entry->nr_fields > field_nr + decode_cond_mask_field) + set_bits (cond->mask, + a2i (entry-> + field[field_nr + decode_cond_mask_field])); + if (entry->nr_fields > field_nr + decode_cond_value_field) + { + if (entry->field[field_nr + decode_cond_value_field][0] == + '!') + { + cond->is_equal = 0; + set_bits (cond->value, + a2i (entry-> + field[field_nr + decode_cond_value_field] + + 1)); + } + else + { + cond->is_equal = 1; + set_bits (cond->value, + a2i (entry-> + field[field_nr + + decode_cond_value_field])); + } + } + if (entry->nr_fields > field_nr + decode_cond_word_nr_field) + cond->word_nr = + a2i (entry->field[field_nr + decode_cond_word_nr_field]); + field_nr += nr_decode_cond_fields; + /* insert it */ + last = &new_rule->conditions; + while (*last != NULL) + last = &(*last)->next; + *last = cond; + } + } + *curr_rule = new_rule; + curr_rule = &new_rule->next; + } + return table; +} + + +int +decode_table_max_word_nr (decode_table *entry) +{ + int max_word_nr = 0; + while (entry != NULL) + { + decode_cond *cond; + if (entry->word_nr > max_word_nr) + max_word_nr = entry->word_nr; + for (cond = entry->conditions; cond != NULL; cond = cond->next) + { + if (cond->word_nr > max_word_nr) + max_word_nr = cond->word_nr; + } + entry = entry->next; + } + return max_word_nr; +} + + + +static void +dump_decode_cond (lf *file, char *prefix, decode_cond *cond, char *suffix) +{ + lf_printf (file, "%s(decode_cond *) 0x%lx", prefix, (long) cond); + if (cond != NULL) + { + lf_indent (file, +1); + lf_printf (file, "\n(word_nr %d)", cond->word_nr); + lf_printf (file, "\n(mask 0x%lx)", (long) cond->mask); + lf_printf (file, "\n(value 0x%lx)", (long) cond->value); + lf_printf (file, "\n(is_equal 0x%lx)", (long) cond->is_equal); + lf_printf (file, "\n(next (decode_cond *) 0%lx)", (long) cond->next); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + + +static void +dump_decode_conds (lf *file, char *prefix, decode_cond *cond, char *suffix) +{ + lf_printf (file, "%s(decode_cond *) 0x%lx", prefix, (long) cond); + while (cond != NULL) + { + dump_decode_cond (file, "\n(", cond, ")"); + cond = cond->next; + } + lf_printf (file, "%s", suffix); +} + + +void +dump_decode_rule (lf *file, char *prefix, decode_table *rule, char *suffix) +{ + lf_printf (file, "%s(decode_table *) 0x%lx", prefix, (long) rule); + if (rule != NULL) + { + lf_indent (file, +1); + dump_line_ref (file, "\n(line ", rule->line, ")"); + lf_printf (file, "\n(type %s)", i2name (rule->type, decode_type_map)); + lf_printf (file, "\n(gen %s)", i2name (rule->gen, decode_gen_map)); + lf_printf (file, "\n(first %d)", rule->first); + lf_printf (file, "\n(last %d)", rule->last); + lf_printf (file, "\n(force_first %d)", rule->force_first); + lf_printf (file, "\n(force_last %d)", rule->force_last); + dump_filter (file, "\n(constant_field_names \"", + rule->constant_field_names, "\")"); + lf_printf (file, "\n(constant 0x%x)", rule->constant); + lf_printf (file, "\n(word_nr %d)", rule->word_nr); + lf_printf (file, "\n(with_zero_reserved %d)", rule->with_zero_reserved); + lf_printf (file, "\n(with_duplicates %d)", rule->with_duplicates); + lf_printf (file, "\n(with_combine %d)", rule->with_combine); + dump_filter (file, "\n(format_names \"", rule->format_names, "\")"); + dump_filter (file, "\n(model_names \"", rule->model_names, "\")"); + dump_decode_conds (file, "\n(conditions ", rule->conditions, ")"); + lf_printf (file, "\n(next 0x%lx)", (long) rule->next); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + + +#ifdef MAIN + +static void +dump_decode_rules (lf *file, char *prefix, decode_table *rule, char *suffix) +{ + lf_printf (file, "%s", prefix); + while (rule != NULL) + { + lf_indent (file, +1); + dump_decode_rule (file, "\n(", rule, ")"); + lf_indent (file, -1); + rule = rule->next; + } + lf_printf (file, "%s", suffix); +} + +igen_options options; + +int +main (int argc, char **argv) +{ + lf *l; + decode_table *rules; + + INIT_OPTIONS (options); + + if (argc != 3) + error (NULL, "Usage: decode \n"); + + options.hi_bit_nr = a2i (argv[2]); + rules = load_decode_table (argv[1]); + l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn"); + dump_decode_rules (l, "(rules ", rules, ")\n"); + + return 0; +} +#endif
ld-decode.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen-engine.h =================================================================== --- gen-engine.h (nonexistent) +++ gen-engine.h (revision 841) @@ -0,0 +1,29 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + +extern void gen_engine_h + (lf *file, gen_table *gen, insn_table *isa, cache_entry *cache_rules); + +extern void gen_engine_c + (lf *file, gen_table *gen, insn_table *isa, cache_entry *cache_rules); + +extern void print_engine_run_function_header + (lf *file, char *processor, function_decl_type decl_type);
gen-engine.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: configure.ac =================================================================== --- configure.ac (nonexistent) +++ configure.ac (revision 841) @@ -0,0 +1,51 @@ +dnl Process this file with autoconf to produce a configure script. +sinclude(../common/aclocal.m4) +AC_PREREQ(2.59)dnl +AC_INIT(table.h) + +AC_PROG_INSTALL +AC_PROG_CC + +SIM_AC_OPTION_WARNINGS + +# Put a plausible default for CC_FOR_BUILD in Makefile. +if test "x$cross_compiling" = "xno" -a "x$host" != "xi386-windows"; then + AR_FOR_BUILD='$(AR)' + AR_FLAGS_FOR_BUILD='$(AR_FLAGS)' + CC_FOR_BUILD='$(CC)' + CFLAGS_FOR_BUILD='$(CFLAGS)' + RANLIB_FOR_BUILD='$(RANLIB)' + LIBIBERTY_LIB=../../libiberty/libiberty.a +else + AR_FOR_BUILD=${AR_FOR_BUILD-ar} + AR_FLAGS_FOR_BUILD=${AR_FLAGS_FOR_BUILD-rc} + CC_FOR_BUILD=${CC_FOR_BUILD-gcc} + CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-"-g"} + RANLIB_FOR_BUILD=${RANLIB_FOR_BUILD-ranlib} + LIBIBERTY_LIB= +fi + + +AC_CANONICAL_SYSTEM +AC_ARG_PROGRAM + +. ${srcdir}/../../bfd/configure.host + +AC_CONFIG_HEADER(config.h:config.in) + +AC_CHECK_HEADERS(stdlib.h string.h strings.h sys/stat.h sys/types.h unistd.h) +AC_HEADER_DIRENT + +AC_SUBST(AR_FOR_BUILD) +AC_SUBST(AR_FLAGS_FOR_BUILD) +AC_SUBST(CC_FOR_BUILD) +AC_SUBST(CFLAGS_FOR_BUILD) +AC_SUBST(RANLIB_FOR_BUILD) +AC_SUBST(LIBIBERTY_LIB) + +AC_SUBST(AR) +AC_SUBST(CFLAGS) +AC_PROG_RANLIB + +AC_OUTPUT(Makefile, +[case x$CONFIG_HEADERS in xconfig.h:config.in) echo > stamp-h ;; esac])
configure.ac Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: ld-decode.h =================================================================== --- ld-decode.h (nonexistent) +++ ld-decode.h (revision 841) @@ -0,0 +1,244 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +/* Instruction decode table: + + ::= + {
ld-decode.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: config.in =================================================================== --- config.in (nonexistent) +++ config.in (revision 841) @@ -0,0 +1,64 @@ +/* config.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* 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 + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS Index: gen-semantics.c =================================================================== --- gen-semantics.c (nonexistent) +++ gen-semantics.c (revision 841) @@ -0,0 +1,379 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + + +#include "misc.h" +#include "lf.h" +#include "table.h" +#include "filter.h" +#include "igen.h" + +#include "ld-insn.h" +#include "ld-decode.h" + +#include "gen.h" + +#include "gen-semantics.h" +#include "gen-icache.h" +#include "gen-idecode.h" + + +static void +print_semantic_function_header (lf *file, + const char *basename, + const char *format_name, + opcode_bits *expanded_bits, + int is_function_definition, + int nr_prefetched_words) +{ + int indent; + lf_printf (file, "\n"); + lf_print__function_type_function (file, print_semantic_function_type, + "EXTERN_SEMANTICS", + (is_function_definition ? "\n" : " ")); + indent = print_function_name (file, + basename, + format_name, + NULL, + expanded_bits, + function_name_prefix_semantics); + if (is_function_definition) + { + indent += lf_printf (file, " "); + lf_indent (file, +indent); + } + else + { + lf_printf (file, "\n"); + } + lf_printf (file, "("); + lf_indent (file, +1); + print_semantic_function_formal (file, nr_prefetched_words); + lf_indent (file, -1); + lf_printf (file, ")"); + if (is_function_definition) + { + lf_indent (file, -indent); + } + else + { + lf_printf (file, ";"); + } + lf_printf (file, "\n"); +} + +void +print_semantic_declaration (lf *file, + insn_entry * insn, + opcode_bits *expanded_bits, + insn_opcodes *opcodes, int nr_prefetched_words) +{ + print_semantic_function_header (file, + insn->name, + insn->format_name, + expanded_bits, + 0 /* is not function definition */ , + nr_prefetched_words); +} + + + +/* generate the semantics.c file */ + + +void +print_idecode_invalid (lf *file, const char *result, invalid_type type) +{ + const char *name; + switch (type) + { + default: + name = "unknown"; + break; + case invalid_illegal: + name = "illegal"; + break; + case invalid_fp_unavailable: + name = "fp_unavailable"; + break; + case invalid_wrong_slot: + name = "wrong_slot"; + break; + } + if (options.gen.code == generate_jumps) + { + lf_printf (file, "goto %s_%s;\n", + (options.gen.icache ? "icache" : "semantic"), name); + } + else if (options.gen.icache) + { + lf_printf (file, "%s %sicache_%s (", result, + options.module.global.prefix.l, name); + print_icache_function_actual (file, 0); + lf_printf (file, ");\n"); + } + else + { + lf_printf (file, "%s %ssemantic_%s (", result, + options.module.global.prefix.l, name); + print_semantic_function_actual (file, 0); + lf_printf (file, ");\n"); + } +} + + +void +print_semantic_body (lf *file, + insn_entry * instruction, + opcode_bits *expanded_bits, insn_opcodes *opcodes) +{ + /* validate the instruction, if a cache this has already been done */ + if (!options.gen.icache) + { + print_idecode_validate (file, instruction, opcodes); + } + + print_itrace (file, instruction, 0 /*put_value_in_cache */ ); + + /* generate the instruction profile call - this is delayed until + after the instruction has been verified. The count macro + generated is prefixed by ITABLE_PREFIX */ + { + lf_printf (file, "\n"); + lf_indent_suppress (file); + lf_printf (file, "#if defined (%sPROFILE_COUNT_INSN)\n", + options.module.itable.prefix.u); + lf_printf (file, "%sPROFILE_COUNT_INSN (CPU, CIA, MY_INDEX);\n", + options.module.itable.prefix.u); + lf_indent_suppress (file); + lf_printf (file, "#endif\n"); + } + + /* generate the model call - this is delayed until after the + instruction has been verified */ + { + lf_printf (file, "\n"); + lf_indent_suppress (file); + lf_printf (file, "#if defined (WITH_MON)\n"); + lf_printf (file, "/* monitoring: */\n"); + lf_printf (file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n"); + lf_printf (file, " mon_issue ("); + print_function_name (file, + instruction->name, + instruction->format_name, + NULL, NULL, function_name_prefix_itable); + lf_printf (file, ", cpu, cia);\n"); + lf_indent_suppress (file); + lf_printf (file, "#endif\n"); + lf_printf (file, "\n"); + } + + /* determine the new instruction address */ + { + lf_printf (file, "/* keep the next instruction address handy */\n"); + if (options.gen.nia == nia_is_invalid) + { + lf_printf (file, "nia = %sINVALID_INSTRUCTION_ADDRESS;\n", + options.module.global.prefix.u); + } + else + { + int nr_immeds = instruction->nr_words - 1; + if (options.gen.delayed_branch) + { + if (nr_immeds > 0) + { + lf_printf (file, "cia.dp += %d * %d; %s\n", + options.insn_bit_size / 8, nr_immeds, + "/* skip dp immeds */"); + } + lf_printf (file, "nia.ip = cia.dp; %s\n", + "/* instruction pointer */"); + lf_printf (file, "nia.dp = cia.dp + %d; %s\n", + options.insn_bit_size / 8, + "/* delayed-slot pointer */"); + } + else + { + if (nr_immeds > 0) + { + lf_printf (file, "nia = cia + %d * (%d + 1); %s\n", + options.insn_bit_size / 8, nr_immeds, + "/* skip immeds as well */"); + + } + else + { + lf_printf (file, "nia = cia + %d;\n", + options.insn_bit_size / 8); + } + } + } + } + + /* if conditional, generate code to verify that the instruction + should be issued */ + if (filter_is_member (instruction->options, "c") + || options.gen.conditional_issue) + { + lf_printf (file, "\n"); + lf_printf (file, "/* execute only if conditional passes */\n"); + lf_printf (file, "if (IS_CONDITION_OK)\n"); + lf_printf (file, " {\n"); + lf_indent (file, +4); + /* FIXME - need to log a conditional failure */ + } + + /* Architecture expects a REG to be zero. Instead of having to + check every read to see if it is refering to that REG just zap it + at the start of every instruction */ + if (options.gen.zero_reg) + { + lf_printf (file, "\n"); + lf_printf (file, "/* Architecture expects REG to be zero */\n"); + lf_printf (file, "GPR_CLEAR(%d);\n", options.gen.zero_reg_nr); + } + + /* generate the code (or at least something */ + lf_printf (file, "\n"); + lf_printf (file, "/* semantics: */\n"); + if (instruction->code != NULL) + { + /* true code */ + lf_printf (file, "{\n"); + lf_indent (file, +2); + lf_print__line_ref (file, instruction->code->line); + table_print_code (file, instruction->code); + lf_indent (file, -2); + lf_printf (file, "}\n"); + lf_print__internal_ref (file); + } + else if (filter_is_member (instruction->options, "nop")) + { + lf_print__internal_ref (file); + } + else + { + const char *prefix = "sim_engine_abort ("; + int indent = strlen (prefix); + /* abort so it is implemented now */ + lf_print__line_ref (file, instruction->line); + lf_printf (file, "%sSD, CPU, cia, \\\n", prefix); + lf_indent (file, +indent); + lf_printf (file, "\"%s:%d:0x%%08lx:%%s unimplemented\\n\", \\\n", + filter_filename (instruction->line->file_name), + instruction->line->line_nr); + lf_printf (file, "(long) CIA, \\\n"); + lf_printf (file, "%sitable[MY_INDEX].name);\n", + options.module.itable.prefix.l); + lf_indent (file, -indent); + lf_print__internal_ref (file); + } + + /* Close off the conditional execution */ + if (filter_is_member (instruction->options, "c") + || options.gen.conditional_issue) + { + lf_indent (file, -4); + lf_printf (file, " }\n"); + } +} + +static void +print_c_semantic (lf *file, + insn_entry * instruction, + opcode_bits *expanded_bits, + insn_opcodes *opcodes, + cache_entry *cache_rules, int nr_prefetched_words) +{ + + lf_printf (file, "{\n"); + lf_indent (file, +2); + + print_my_defines (file, + instruction->name, + instruction->format_name, expanded_bits); + lf_printf (file, "\n"); + print_icache_body (file, + instruction, + expanded_bits, + cache_rules, + (options.gen.direct_access + ? define_variables + : declare_variables), + (options.gen.icache + ? get_values_from_icache + : do_not_use_icache), nr_prefetched_words); + + lf_printf (file, "%sinstruction_address nia;\n", + options.module.global.prefix.l); + print_semantic_body (file, instruction, expanded_bits, opcodes); + lf_printf (file, "return nia;\n"); + + /* generate something to clean up any #defines created for the cache */ + if (options.gen.direct_access) + { + print_icache_body (file, + instruction, + expanded_bits, + cache_rules, + undef_variables, + (options.gen.icache + ? get_values_from_icache + : do_not_use_icache), nr_prefetched_words); + } + + lf_indent (file, -2); + lf_printf (file, "}\n"); +} + +static void +print_c_semantic_function (lf *file, + insn_entry * instruction, + opcode_bits *expanded_bits, + insn_opcodes *opcodes, + cache_entry *cache_rules, int nr_prefetched_words) +{ + /* build the semantic routine to execute the instruction */ + print_semantic_function_header (file, + instruction->name, + instruction->format_name, + expanded_bits, + 1 /*is-function-definition */ , + nr_prefetched_words); + print_c_semantic (file, + instruction, + expanded_bits, opcodes, cache_rules, nr_prefetched_words); +} + +void +print_semantic_definition (lf *file, + insn_entry * insn, + opcode_bits *expanded_bits, + insn_opcodes *opcodes, + cache_entry *cache_rules, int nr_prefetched_words) +{ + print_c_semantic_function (file, + insn, + expanded_bits, + opcodes, cache_rules, nr_prefetched_words); +}
gen-semantics.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: lf.c =================================================================== --- lf.c (nonexistent) +++ lf.c (revision 841) @@ -0,0 +1,424 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + + +#include +#include +#include + +#include "config.h" +#include "misc.h" +#include "lf.h" + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + +struct _lf +{ + FILE *stream; + int line_nr; /* nr complete lines written, curr line is line_nr+1 */ + int indent; + int line_blank; + const char *name; + const char *program; + lf_file_references references; + lf_file_type type; +}; + + +lf * +lf_open (char *name, + char *real_name, + lf_file_references references, + lf_file_type type, const char *program) +{ + /* create a file object */ + lf *new_lf = ZALLOC (lf); + ASSERT (new_lf != NULL); + new_lf->references = references; + new_lf->type = type; + new_lf->name = (real_name == NULL ? name : real_name); + new_lf->program = program; + /* attach to stdout if pipe */ + if (!strcmp (name, "-")) + { + new_lf->stream = stdout; + } + else + { + /* create a new file */ + new_lf->stream = fopen (name, "w"); + if (new_lf->stream == NULL) + { + perror (name); + exit (1); + } + } + return new_lf; +} + + +void +lf_close (lf *file) +{ + if (file->stream != stdout) + { + if (fclose (file->stream)) + { + perror ("lf_close.fclose"); + exit (1); + } + free (file); + } +} + + +int +lf_putchr (lf *file, const char chr) +{ + int nr = 0; + if (chr == '\n') + { + file->line_nr += 1; + file->line_blank = 1; + } + else if (file->line_blank) + { + int pad; + for (pad = file->indent; pad > 0; pad--) + putc (' ', file->stream); + nr += file->indent; + file->line_blank = 0; + } + putc (chr, file->stream); + nr += 1; + return nr; +} + +int +lf_write (lf *file, const char *string, int strlen_string) +{ + int nr = 0; + int i; + for (i = 0; i < strlen_string; i++) + nr += lf_putchr (file, string[i]); + return nr; +} + + +void +lf_indent_suppress (lf *file) +{ + file->line_blank = 0; +} + + +int +lf_putstr (lf *file, const char *string) +{ + int nr = 0; + const char *chp; + if (string != NULL) + { + for (chp = string; *chp != '\0'; chp++) + { + nr += lf_putchr (file, *chp); + } + } + return nr; +} + +static int +do_lf_putunsigned (lf *file, unsigned u) +{ + int nr = 0; + if (u > 0) + { + nr += do_lf_putunsigned (file, u / 10); + nr += lf_putchr (file, (u % 10) + '0'); + } + return nr; +} + + +int +lf_putint (lf *file, int decimal) +{ + int nr = 0; + if (decimal == 0) + nr += lf_putchr (file, '0'); + else if (decimal < 0) + { + nr += lf_putchr (file, '-'); + nr += do_lf_putunsigned (file, -decimal); + } + else if (decimal > 0) + { + nr += do_lf_putunsigned (file, decimal); + } + else + ASSERT (0); + return nr; +} + + +int +lf_printf (lf *file, const char *fmt, ...) +{ + int nr = 0; + char buf[1024]; + va_list ap; + + va_start (ap, fmt); + vsprintf (buf, fmt, ap); + /* FIXME - this is really stuffed but so is vsprintf() on a sun! */ + ASSERT (strlen (buf) < sizeof (buf)); + nr += lf_putstr (file, buf); + va_end (ap); + return nr; +} + + +int +lf_print__line_ref (lf *file, line_ref *line) +{ + return lf_print__external_ref (file, line->line_nr, line->file_name); +} + +int +lf_print__external_ref (lf *file, int line_nr, const char *file_name) +{ + int nr = 0; + switch (file->references) + { + case lf_include_references: + lf_indent_suppress (file); + nr += lf_putstr (file, "#line "); + nr += lf_putint (file, line_nr); + nr += lf_putstr (file, " \""); + nr += lf_putstr (file, file_name); + nr += lf_putstr (file, "\"\n"); + break; + case lf_omit_references: + nr += lf_putstr (file, "/* "); + nr += lf_putstr (file, file_name); + nr += lf_putstr (file, ":"); + nr += lf_putint (file, line_nr); + nr += lf_putstr (file, "*/\n"); + break; + } + return nr; +} + +int +lf_print__internal_ref (lf *file) +{ + int nr = 0; + nr += lf_print__external_ref (file, file->line_nr + 2, file->name); + /* line_nr == last_line, want to number from next */ + return nr; +} + +void +lf_indent (lf *file, int delta) +{ + file->indent += delta; +} + + +int +lf_print__gnu_copyleft (lf *file) +{ + int nr = 0; + switch (file->type) + { + case lf_is_c: + case lf_is_h: + nr += lf_printf (file, "\ +/* This file is part of GDB.\n\ +\n\ + Copyright 2002, 2007 Free Software Foundation, Inc.\n\ +\n\ + This program is free software; you can redistribute it and/or modify\n\ + it under the terms of the GNU General Public License as published by\n\ + the Free Software Foundation; either version 3 of the License, or\n\ + (at your option) any later version.\n\ +\n\ + This program is distributed in the hope that it will be useful,\n\ + but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ + GNU General Public License for more details.\n\ +\n\ + You should have received a copy of the GNU General Public License\n\ + along with this program. If not, see .\n\ +\n\ + --\n\ +\n\ + This file was generated by the program %s */\n\ +", filter_filename (file->program)); + break; + default: + ASSERT (0); + break; + } + return nr; +} + + +int +lf_putbin (lf *file, int decimal, int width) +{ + int nr = 0; + int bit; + ASSERT (width > 0); + for (bit = 1 << (width - 1); bit != 0; bit >>= 1) + { + if (decimal & bit) + nr += lf_putchr (file, '1'); + else + nr += lf_putchr (file, '0'); + } + return nr; +} + +int +lf_print__this_file_is_empty (lf *file, const char *reason) +{ + int nr = 0; + switch (file->type) + { + case lf_is_c: + case lf_is_h: + nr += lf_printf (file, + "/* This generated file (%s) is intentionally left blank", + file->name); + if (reason != NULL) + nr += lf_printf (file, " - %s", reason); + nr += lf_printf (file, " */\n"); + break; + default: + ERROR ("Bad switch"); + } + return nr; +} + +int +lf_print__ucase_filename (lf *file) +{ + int nr = 0; + const char *chp = file->name; + while (*chp != '\0') + { + char ch = *chp; + if (islower (ch)) + { + nr += lf_putchr (file, toupper (ch)); + } + else if (ch == '.') + nr += lf_putchr (file, '_'); + else + nr += lf_putchr (file, ch); + chp++; + } + return nr; +} + +int +lf_print__file_start (lf *file) +{ + int nr = 0; + switch (file->type) + { + case lf_is_h: + case lf_is_c: + nr += lf_print__gnu_copyleft (file); + nr += lf_printf (file, "\n"); + nr += lf_printf (file, "#ifndef "); + nr += lf_print__ucase_filename (file); + nr += lf_printf (file, "\n"); + nr += lf_printf (file, "#define "); + nr += lf_print__ucase_filename (file); + nr += lf_printf (file, "\n"); + nr += lf_printf (file, "\n"); + break; + default: + ASSERT (0); + } + return nr; +} + + +int +lf_print__file_finish (lf *file) +{ + int nr = 0; + switch (file->type) + { + case lf_is_h: + case lf_is_c: + nr += lf_printf (file, "\n"); + nr += lf_printf (file, "#endif /* _"); + nr += lf_print__ucase_filename (file); + nr += lf_printf (file, "_*/\n"); + break; + default: + ASSERT (0); + } + return nr; +} + + +int +lf_print__function_type (lf *file, + const char *type, + const char *prefix, const char *trailing_space) +{ + int nr = 0; + nr += lf_printf (file, "%s\\\n(%s)", prefix, type); + if (trailing_space != NULL) + nr += lf_printf (file, "%s", trailing_space); + return nr; +} + +int +lf_print__function_type_function (lf *file, + print_function * print_type, + const char *prefix, + const char *trailing_space) +{ + int nr = 0; + nr += lf_printf (file, "%s\\\n(", prefix); + nr += print_type (file); + nr += lf_printf (file, ")"); + if (trailing_space != NULL) + nr += lf_printf (file, "%s", trailing_space); + return nr; +}
lf.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen-semantics.h =================================================================== --- gen-semantics.h (nonexistent) +++ gen-semantics.h (revision 841) @@ -0,0 +1,99 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +/* Creates the files semantics.[hc]. + + The generated file semantics contains functions that implement the + operations required to model a single target processor instruction. + + Several different variations on the semantics file can be created: + + o uncached + + No instruction cache exists. The semantic function + needs to generate any required values locally. + + o cached - separate cracker and semantic + + Two independant functions are created. Firstly the + function that cracks an instruction entering it into a + cache and secondly the semantic function propper that + uses the cache. + + o cached - semantic + cracking semantic + + The function that cracks the instruction and enters + all values into the cache also contains a copy of the + semantic code (avoiding the need to call both the + cracker and the semantic function when there is a + cache miss). + + For each of these general forms, several refinements can occure: + + o do/don't duplicate/expand semantic functions + + As a consequence of decoding an instruction, the + decoder, as part of its table may have effectivly made + certain of the variable fields in an instruction + constant. Separate functions for each of the + alternative values for what would have been treated as + a variable part can be created. + + o use cache struct directly. + + When a cracking cache is present, the semantic + functions can be generated to either hold intermediate + cache values in local variables or always refer to the + contents of the cache directly. */ + + + + + + +extern void print_semantic_declaration + (lf *file, + insn_entry * insn, + opcode_bits *bits, insn_opcodes *opcodes, int nr_prefetched_words); + +extern void print_semantic_definition + (lf *file, + insn_entry * insn, + opcode_bits *bits, + insn_opcodes *opcodes, cache_entry *cache_rules, int nr_prefetched_words); + + +typedef enum +{ + invalid_illegal, + invalid_fp_unavailable, + invalid_wrong_slot, +} +invalid_type; + +extern void print_idecode_invalid + (lf *file, const char *result, invalid_type type); + +extern void print_semantic_body + (lf *file, + insn_entry * instruction, + opcode_bits *expanded_bits, insn_opcodes *opcodes);
gen-semantics.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen-idecode.c =================================================================== --- gen-idecode.c (nonexistent) +++ gen-idecode.c (revision 841) @@ -0,0 +1,1304 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +#include "misc.h" +#include "lf.h" +#include "table.h" +#include "filter.h" +#include "igen.h" + +#include "ld-insn.h" +#include "ld-decode.h" + +#include "gen.h" + +#include "gen-idecode.h" +#include "gen-icache.h" +#include "gen-semantics.h" + + + +static void +lf_print_opcodes (lf *file, gen_entry *table) +{ + if (table !=NULL) + { + while (1) + { + ASSERT (table->opcode != NULL); + lf_printf (file, "_%d_%d", + table->opcode->first, table->opcode->last); + if (table->parent == NULL) + break; + lf_printf (file, "__%d", table->opcode_nr); + table = table->parent; + } + } +} + + + + +static void +print_idecode_ifetch (lf *file, + int previous_nr_prefetched_words, + int current_nr_prefetched_words) +{ + int word_nr; + for (word_nr = previous_nr_prefetched_words; + word_nr < current_nr_prefetched_words; word_nr++) + { + lf_printf (file, + "instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n", + word_nr, options.insn_bit_size, word_nr); + + } +} + + + +/****************************************************************/ + + +static void +lf_print_table_name (lf *file, gen_entry *table) +{ + lf_printf (file, "idecode_table"); + lf_print_opcodes (file, table); +} + + + +static void +print_idecode_table (lf *file, gen_entry *entry, const char *result) +{ + lf_printf (file, "/* prime the search */\n"); + lf_printf (file, "idecode_table_entry *table = "); + lf_print_table_name (file, entry); + lf_printf (file, ";\n"); + lf_printf (file, "int opcode = EXTRACTED%d (instruction, %d, %d);\n", + options.insn_bit_size, + i2target (options.hi_bit_nr, entry->opcode->first), + i2target (options.hi_bit_nr, entry->opcode->last)); + lf_printf (file, "idecode_table_entry *table_entry = table + opcode;\n"); + + lf_printf (file, "\n"); + lf_printf (file, "/* iterate until a leaf */\n"); + lf_printf (file, "while (1) {\n"); + lf_printf (file, " signed shift = table_entry->shift;\n"); + lf_printf (file, "if (shift == function_entry) break;\n"); + lf_printf (file, " if (shift >= 0) {\n"); + lf_printf (file, " table = ((idecode_table_entry*)\n"); + lf_printf (file, " table_entry->function_or_table);\n"); + lf_printf (file, " opcode = ((instruction & table_entry->mask)\n"); + lf_printf (file, " >> shift);\n"); + lf_printf (file, " table_entry = table + opcode;\n"); + lf_printf (file, " }\n"); + lf_printf (file, " else {\n"); + lf_printf (file, " /* must be a boolean */\n"); + lf_printf (file, " ASSERT(table_entry->shift == boolean_entry);\n"); + lf_printf (file, " opcode = ((instruction & table_entry->mask)\n"); + lf_printf (file, " != table_entry->value);\n"); + lf_printf (file, " table = ((idecode_table_entry*)\n"); + lf_printf (file, " table_entry->function_or_table);\n"); + lf_printf (file, " table_entry = table + opcode;\n"); + lf_printf (file, " }\n"); + lf_printf (file, "}\n"); + + lf_printf (file, "\n"); + lf_printf (file, "/* call the leaf code */\n"); + if (options.gen.code == generate_jumps) + { + lf_printf (file, "goto *table_entry->function_or_table;\n"); + } + else + { + lf_printf (file, "%s ", result); + if (options.gen.icache) + { + lf_printf (file, + "(((idecode_icache*)table_entry->function_or_table)\n"); + lf_printf (file, " ("); + print_icache_function_actual (file, 1); + lf_printf (file, "));\n"); + } + else + { + lf_printf (file, + "((idecode_semantic*)table_entry->function_or_table)\n"); + lf_printf (file, " ("); + print_semantic_function_actual (file, 1); + lf_printf (file, ");\n"); + } + } +} + + +static void +print_idecode_table_start (lf *file, gen_entry *table, int depth, void *data) +{ + ASSERT (depth == 0); + /* start of the table */ + if (table->opcode_rule->gen == array_gen) + { + lf_printf (file, "\n"); + lf_printf (file, "static idecode_table_entry "); + lf_print_table_name (file, table); + lf_printf (file, "[] = {\n"); + } +} + +static void +print_idecode_table_leaf (lf *file, gen_entry *entry, int depth, void *data) +{ + gen_entry *master_entry; + ASSERT (entry->parent != NULL); + ASSERT (depth == 0); + if (entry->combined_parent == NULL) + master_entry = entry; + else + master_entry = entry->combined_parent; + + /* add an entry to the table */ + if (entry->parent->opcode_rule->gen == array_gen) + { + lf_printf (file, " /*%d*/ { ", entry->opcode_nr); + if (entry->opcode == NULL) + { + ASSERT (entry->nr_insns == 1); + /* table leaf entry */ + lf_printf (file, "function_entry, 0, 0, "); + if (options.gen.code == generate_jumps) + { + lf_printf (file, "&&"); + } + print_function_name (file, + entry->insns->insn->name, + entry->insns->insn->format_name, + NULL, + master_entry->expanded_bits, + (options.gen.icache + ? function_name_prefix_icache + : function_name_prefix_semantics)); + } + else if (entry->opcode_rule->gen == switch_gen + || entry->opcode_rule->gen == goto_switch_gen + || entry->opcode_rule->gen == padded_switch_gen) + { + /* table calling switch statement */ + lf_printf (file, "function_entry, 0, 0, "); + if (options.gen.code == generate_jumps) + { + lf_printf (file, "&&"); + } + lf_print_table_name (file, entry); + } + else if (entry->opcode->is_boolean) + { + /* table `calling' boolean table */ + lf_printf (file, "boolean_entry, "); + lf_printf (file, "MASK32(%d, %d), ", + i2target (options.hi_bit_nr, entry->opcode->first), + i2target (options.hi_bit_nr, entry->opcode->last)); + lf_printf (file, "INSERTED32(%d, %d, %d), ", + entry->opcode->boolean_constant, + i2target (options.hi_bit_nr, entry->opcode->first), + i2target (options.hi_bit_nr, entry->opcode->last)); + lf_print_table_name (file, entry); + } + else + { + /* table `calling' another table */ + lf_printf (file, "%d, ", + options.insn_bit_size - entry->opcode->last - 1); + lf_printf (file, "MASK%d(%d,%d), ", options.insn_bit_size, + i2target (options.hi_bit_nr, entry->opcode->first), + i2target (options.hi_bit_nr, entry->opcode->last)); + lf_printf (file, "0, "); + lf_print_table_name (file, entry); + } + lf_printf (file, " },\n"); + } +} + +static void +print_idecode_table_end (lf *file, gen_entry *table, int depth, void *data) +{ + ASSERT (depth == 0); + if (table->opcode_rule->gen == array_gen) + { + lf_printf (file, "};\n"); + } +} + +/****************************************************************/ + + +static void +print_goto_switch_name (lf *file, gen_entry *entry) +{ + lf_printf (file, "case_"); + if (entry->opcode == NULL) + { + print_function_name (file, + entry->insns->insn->name, + entry->insns->insn->format_name, + NULL, + entry->expanded_bits, + (options.gen.icache + ? function_name_prefix_icache + : function_name_prefix_semantics)); + } + else + { + lf_print_table_name (file, entry); + } +} + +static void +print_goto_switch_table_leaf (lf *file, + gen_entry *entry, int depth, void *data) +{ + ASSERT (entry->parent != NULL); + ASSERT (depth == 0); + ASSERT (entry->parent->opcode_rule->gen == goto_switch_gen); + ASSERT (entry->parent->opcode); + + lf_printf (file, "/* %d */ &&", entry->opcode_nr); + if (entry->combined_parent != NULL) + print_goto_switch_name (file, entry->combined_parent); + else + print_goto_switch_name (file, entry); + lf_printf (file, ",\n"); +} + +static void +print_goto_switch_break (lf *file, gen_entry *entry) +{ + lf_printf (file, "goto break_"); + lf_print_table_name (file, entry->parent); + lf_printf (file, ";\n"); +} + + +static void +print_goto_switch_table (lf *file, gen_entry *table) +{ + lf_printf (file, "const static void *"); + lf_print_table_name (file, table); + lf_printf (file, "[] = {\n"); + lf_indent (file, +2); + gen_entry_traverse_tree (file, table, 0, NULL /*start */ , + print_goto_switch_table_leaf, NULL /*end */ , + NULL /*data */ ); + lf_indent (file, -2); + lf_printf (file, "};\n"); +} + + +void print_idecode_switch (lf *file, gen_entry *table, const char *result); + +static void +print_idecode_switch_start (lf *file, gen_entry *table, int depth, void *data) +{ + /* const char *result = data; */ + ASSERT (depth == 0); + ASSERT (table->opcode_rule->gen == switch_gen + || table->opcode_rule->gen == goto_switch_gen + || table->opcode_rule->gen == padded_switch_gen); + + if (table->opcode->is_boolean + || table->opcode_rule->gen == switch_gen + || table->opcode_rule->gen == padded_switch_gen) + { + lf_printf (file, "switch (EXTRACTED%d (instruction_%d, %d, %d))\n", + options.insn_bit_size, + table->opcode_rule->word_nr, + i2target (options.hi_bit_nr, table->opcode->first), + i2target (options.hi_bit_nr, table->opcode->last)); + lf_indent (file, +2); + lf_printf (file, "{\n"); + } + else if (table->opcode_rule->gen == goto_switch_gen) + { + if (table->parent != NULL + && (table->parent->opcode_rule->gen == switch_gen + || table->parent->opcode_rule->gen == goto_switch_gen + || table->parent->opcode_rule->gen == padded_switch_gen)) + { + lf_printf (file, "{\n"); + lf_indent (file, +2); + } + print_goto_switch_table (file, table); + lf_printf (file, "ASSERT (EXTRACTED%d (instruction_%d, %d, %d)\n", + options.insn_bit_size, + table->opcode->word_nr, + i2target (options.hi_bit_nr, table->opcode->first), + i2target (options.hi_bit_nr, table->opcode->last)); + lf_printf (file, " < (sizeof ("); + lf_print_table_name (file, table); + lf_printf (file, ") / sizeof(void*)));\n"); + lf_printf (file, "goto *"); + lf_print_table_name (file, table); + lf_printf (file, "[EXTRACTED%d (instruction_%d, %d, %d)];\n", + options.insn_bit_size, + table->opcode->word_nr, + i2target (options.hi_bit_nr, table->opcode->first), + i2target (options.hi_bit_nr, table->opcode->last)); + } + else + { + ASSERT ("bad switch" == NULL); + } +} + + +static void +print_idecode_switch_leaf (lf *file, gen_entry *entry, int depth, void *data) +{ + const char *result = data; + ASSERT (entry->parent != NULL); + ASSERT (depth == 0); + ASSERT (entry->parent->opcode_rule->gen == switch_gen + || entry->parent->opcode_rule->gen == goto_switch_gen + || entry->parent->opcode_rule->gen == padded_switch_gen); + ASSERT (entry->parent->opcode); + + /* skip over any instructions combined into another entry */ + if (entry->combined_parent != NULL) + return; + + if (entry->parent->opcode->is_boolean && entry->opcode_nr == 0) + { + /* case: boolean false target */ + lf_printf (file, "case %d:\n", entry->parent->opcode->boolean_constant); + } + else if (entry->parent->opcode->is_boolean && entry->opcode_nr != 0) + { + /* case: boolean true case */ + lf_printf (file, "default:\n"); + } + else if (entry->parent->opcode_rule->gen == switch_gen + || entry->parent->opcode_rule->gen == padded_switch_gen) + { + /* case: - switch */ + gen_entry *cob; + for (cob = entry; cob != NULL; cob = cob->combined_next) + lf_printf (file, "case %d:\n", cob->opcode_nr); + } + else if (entry->parent->opcode_rule->gen == goto_switch_gen) + { + /* case: - goto-switch */ + print_goto_switch_name (file, entry); + lf_printf (file, ":\n"); + } + else + { + ERROR ("bad switch"); + } + lf_printf (file, " {\n"); + lf_indent (file, +4); + { + if (entry->opcode == NULL) + { + /* switch calling leaf */ + ASSERT (entry->nr_insns == 1); + print_idecode_ifetch (file, entry->nr_prefetched_words, + entry->insns->semantic->nr_prefetched_words); + switch (options.gen.code) + { + case generate_jumps: + lf_printf (file, "goto "); + break; + case generate_calls: + lf_printf (file, "%s", result); + break; + } + print_function_name (file, + entry->insns->insn->name, + entry->insns->insn->format_name, + NULL, + entry->expanded_bits, + (options.gen.icache + ? function_name_prefix_icache + : function_name_prefix_semantics)); + if (options.gen.code == generate_calls) + { + lf_printf (file, " ("); + print_semantic_function_actual (file, + entry->insns->semantic-> + nr_prefetched_words); + lf_printf (file, ")"); + } + lf_printf (file, ";\n"); + } + else if (entry->opcode_rule->gen == switch_gen + || entry->opcode_rule->gen == goto_switch_gen + || entry->opcode_rule->gen == padded_switch_gen) + { + /* switch calling switch */ + lf_printf (file, "{\n"); + lf_indent (file, +2); + print_idecode_ifetch (file, entry->parent->nr_prefetched_words, + entry->nr_prefetched_words); + print_idecode_switch (file, entry, result); + lf_indent (file, -2); + lf_printf (file, "}\n"); + } + else + { + /* switch looking up a table */ + lf_printf (file, "{\n"); + lf_indent (file, +2); + print_idecode_ifetch (file, entry->parent->nr_prefetched_words, + entry->nr_prefetched_words); + print_idecode_table (file, entry, result); + lf_indent (file, -2); + lf_printf (file, "}\n"); + } + if (entry->parent->opcode->is_boolean + || entry->parent->opcode_rule->gen == switch_gen + || entry->parent->opcode_rule->gen == padded_switch_gen) + { + lf_printf (file, "break;\n"); + } + else if (entry->parent->opcode_rule->gen == goto_switch_gen) + { + print_goto_switch_break (file, entry); + } + else + { + ERROR ("bad switch"); + } + } + lf_indent (file, -4); + lf_printf (file, " }\n"); +} + + +static void +print_idecode_switch_illegal (lf *file, const char *result) +{ + lf_indent (file, +2); + print_idecode_invalid (file, result, invalid_illegal); + lf_printf (file, "break;\n"); + lf_indent (file, -2); +} + +static void +print_idecode_switch_end (lf *file, gen_entry *table, int depth, void *data) +{ + const char *result = data; + ASSERT (depth == 0); + ASSERT (table->opcode_rule->gen == switch_gen + || table->opcode_rule->gen == goto_switch_gen + || table->opcode_rule->gen == padded_switch_gen); + ASSERT (table->opcode); + + if (table->opcode->is_boolean) + { + lf_printf (file, "}\n"); + lf_indent (file, -2); + } + else if (table->opcode_rule->gen == switch_gen + || table->opcode_rule->gen == padded_switch_gen) + { + lf_printf (file, "default:\n"); + lf_indent (file, +2); + if (table->nr_entries == table->opcode->nr_opcodes) + { + print_sim_engine_abort (file, + "Internal error - bad switch generated"); + lf_printf (file, "%sNULL_CIA;\n", result); + lf_printf (file, "break;\n"); + } + else + { + print_idecode_switch_illegal (file, result); + } + lf_indent (file, -2); + lf_printf (file, "}\n"); + lf_indent (file, -2); + } + else if (table->opcode_rule->gen == goto_switch_gen) + { + lf_printf (file, "illegal_"); + lf_print_table_name (file, table); + lf_printf (file, ":\n"); + print_idecode_invalid (file, result, invalid_illegal); + lf_printf (file, "break_"); + lf_print_table_name (file, table); + lf_printf (file, ":;\n"); + if (table->parent != NULL + && (table->parent->opcode_rule->gen == switch_gen + || table->parent->opcode_rule->gen == goto_switch_gen + || table->parent->opcode_rule->gen == padded_switch_gen)) + { + lf_indent (file, -2); + lf_printf (file, "}\n"); + } + } + else + { + ERROR ("bad switch"); + } +} + + +void +print_idecode_switch (lf *file, gen_entry *table, const char *result) +{ + gen_entry_traverse_tree (file, table, + 0, + print_idecode_switch_start, + print_idecode_switch_leaf, + print_idecode_switch_end, (void *) result); +} + + +static void +print_idecode_switch_function_header (lf *file, + gen_entry *table, + int is_function_definition, + int nr_prefetched_words) +{ + lf_printf (file, "\n"); + if (options.gen.code == generate_calls) + { + lf_printf (file, "static "); + if (options.gen.icache) + { + lf_printf (file, "idecode_semantic *"); + } + else + { + lf_printf (file, "unsigned_word"); + } + if (is_function_definition) + { + lf_printf (file, "\n"); + } + else + { + lf_printf (file, " "); + } + lf_print_table_name (file, table); + lf_printf (file, "\n("); + print_icache_function_formal (file, nr_prefetched_words); + lf_printf (file, ")"); + if (!is_function_definition) + { + lf_printf (file, ";"); + } + lf_printf (file, "\n"); + } + if (options.gen.code == generate_jumps && is_function_definition) + { + lf_indent (file, -1); + lf_print_table_name (file, table); + lf_printf (file, ":\n"); + lf_indent (file, +1); + } +} + + +static void +idecode_declare_if_switch (lf *file, gen_entry *table, int depth, void *data) +{ + if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL /* don't declare the top one yet */ + && table->parent->opcode_rule->gen == array_gen) + { + print_idecode_switch_function_header (file, + table, + 0 /*isnt function definition */ , + 0); + } +} + + +static void +idecode_expand_if_switch (lf *file, gen_entry *table, int depth, void *data) +{ + if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL /* don't expand the top one yet */ + && table->parent->opcode_rule->gen == array_gen) + { + print_idecode_switch_function_header (file, + table, + 1 /*is function definition */ , + 0); + if (options.gen.code == generate_calls) + { + lf_printf (file, "{\n"); + lf_indent (file, +2); + } + print_idecode_switch (file, table, "return"); + if (options.gen.code == generate_calls) + { + lf_indent (file, -2); + lf_printf (file, "}\n"); + } + } +} + + +/****************************************************************/ + + +void +print_idecode_lookups (lf *file, gen_entry *table, cache_entry *cache_rules) +{ + int depth; + + /* output switch function declarations where needed by tables */ + gen_entry_traverse_tree (file, table, 1, idecode_declare_if_switch, /* START */ + NULL, NULL, NULL); + + /* output tables where needed */ + for (depth = gen_entry_depth (table); depth > 0; depth--) + { + gen_entry_traverse_tree (file, table, + 1 - depth, + print_idecode_table_start, + print_idecode_table_leaf, + print_idecode_table_end, NULL); + } + + /* output switch functions where needed */ + gen_entry_traverse_tree (file, table, 1, idecode_expand_if_switch, /* START */ + NULL, NULL, NULL); +} + + +void +print_idecode_body (lf *file, gen_entry *table, const char *result) +{ + if (table->opcode_rule->gen == switch_gen + || table->opcode_rule->gen == goto_switch_gen + || table->opcode_rule->gen == padded_switch_gen) + { + print_idecode_switch (file, table, result); + } + else + { + print_idecode_table (file, table, result); + } +} + + +/****************************************************************/ + +#if 0 +static void +print_jump (lf *file, int is_tail) +{ + if (is_tail) + { + lf_putstr (file, "if (keep_running != NULL && !*keep_running)\n"); + lf_putstr (file, " cpu_halt(cpu, nia, was_continuing, 0/*na*/);\n"); + } + + if (!options.generate_smp) + { + lf_putstr (file, "if (WITH_EVENTS) {\n"); + lf_putstr (file, " if (event_queue_tick(events)) {\n"); + lf_putstr (file, " cpu_set_program_counter(cpu, nia);\n"); + lf_putstr (file, " event_queue_process(events);\n"); + lf_putstr (file, " nia = cpu_get_program_counter(cpu);\n"); + lf_putstr (file, " }\n"); + lf_putstr (file, "}\n"); + } + + if (options.generate_smp) + { + if (is_tail) + { + lf_putstr (file, "cpu_set_program_counter(cpu, nia);\n"); + } + lf_putstr (file, "if (WITH_EVENTS) {\n"); + lf_putstr (file, " current_cpu += 1;\n"); + lf_putstr (file, " if (current_cpu >= nr_cpus) {\n"); + lf_putstr (file, " if (event_queue_tick(events)) {\n"); + lf_putstr (file, " event_queue_process(events);\n"); + lf_putstr (file, " }\n"); + lf_putstr (file, " current_cpu = 0;\n"); + lf_putstr (file, " }\n"); + lf_putstr (file, "}\n"); + lf_putstr (file, "else {\n"); + lf_putstr (file, " current_cpu = (current_cpu + 1) % nr_cpus;\n"); + lf_putstr (file, "}\n"); + lf_putstr (file, "cpu = cpus[current_cpu];\n"); + lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n"); + } + + if (options.gen.icache) + { + lf_putstr (file, "cache_entry = cpu_icache_entry(cpu, nia);\n"); + lf_putstr (file, "if (cache_entry->address == nia) {\n"); + lf_putstr (file, " /* cache hit */\n"); + lf_putstr (file, " goto *cache_entry->semantic;\n"); + lf_putstr (file, "}\n"); + if (is_tail) + { + lf_putstr (file, "goto cache_miss;\n"); + } + } + + if (!options.gen.icache && is_tail) + { + lf_printf (file, "goto idecode;\n"); + } + +} +#endif + + + +#if 0 +static void +print_jump_insn (lf *file, + insn_entry * instruction, + insn_bits * expanded_bits, + opcode_field *opcodes, cache_entry *cache_rules) +{ + + /* what we are for the moment */ + lf_printf (file, "\n"); + print_my_defines (file, expanded_bits, instruction->name); + + /* output the icache entry */ + if (options.gen.icache) + { + lf_printf (file, "\n"); + lf_indent (file, -1); + print_function_name (file, + instruction->name, + expanded_bits, function_name_prefix_icache); + lf_printf (file, ":\n"); + lf_indent (file, +1); + lf_printf (file, "{\n"); + lf_indent (file, +2); + lf_putstr (file, "const unsigned_word cia = nia;\n"); + print_itrace (file, instruction, 1 /*putting-value-in-cache */ ); + print_idecode_validate (file, instruction, opcodes); + lf_printf (file, "\n"); + lf_printf (file, "{\n"); + lf_indent (file, +2); + print_icache_body (file, instruction, expanded_bits, cache_rules, 0, /*use_defines */ + put_values_in_icache); + lf_printf (file, "cache_entry->address = nia;\n"); + lf_printf (file, "cache_entry->semantic = &&"); + print_function_name (file, + instruction->name, + expanded_bits, function_name_prefix_semantics); + lf_printf (file, ";\n"); + if (options.gen.semantic_icache) + { + print_semantic_body (file, instruction, expanded_bits, opcodes); + print_jump (file, 1 /*is-tail */ ); + } + else + { + lf_printf (file, "/* goto "); + print_function_name (file, + instruction->name, + expanded_bits, function_name_prefix_semantics); + lf_printf (file, "; */\n"); + } + lf_indent (file, -2); + lf_putstr (file, "}\n"); + lf_indent (file, -2); + lf_printf (file, "}\n"); + } + + /* print the semantics */ + lf_printf (file, "\n"); + lf_indent (file, -1); + print_function_name (file, + instruction->name, + expanded_bits, function_name_prefix_semantics); + lf_printf (file, ":\n"); + lf_indent (file, +1); + lf_printf (file, "{\n"); + lf_indent (file, +2); + lf_putstr (file, "const unsigned_word cia = nia;\n"); + print_icache_body (file, + instruction, + expanded_bits, + cache_rules, + (options.gen.direct_access + ? define_variables + : declare_variables), + (options.gen.icache + ? get_values_from_icache : do_not_use_icache)); + print_semantic_body (file, instruction, expanded_bits, opcodes); + if (options.gen.direct_access) + print_icache_body (file, + instruction, + expanded_bits, + cache_rules, + undef_variables, + (options.gen.icache + ? get_values_from_icache : do_not_use_icache)); + print_jump (file, 1 /*is tail */ ); + lf_indent (file, -2); + lf_printf (file, "}\n"); +} +#endif + + +#if 0 +static void +print_jump_definition (lf *file, + gen_entry *entry, + insn_entry * insn, int depth, void *data) +{ + cache_entry *cache_rules = (cache_entry *) data; + if (options.generate_expanded_instructions) + { + ASSERT (entry->nr_insns == 1 + && entry->opcode == NULL + && entry->parent != NULL && entry->parent->opcode != NULL); + ASSERT (entry->nr_insns == 1 + && entry->opcode == NULL + && entry->parent != NULL + && entry->parent->opcode != NULL + && entry->parent->opcode_rule != NULL); + print_jump_insn (file, + entry->insns->words[0]->insn, + entry->expanded_bits, entry->opcode, cache_rules); + } + else + { + print_jump_insn (file, + instruction->words[0]->insn, NULL, NULL, cache_rules); + } +} +#endif + +#if 0 +static void +print_jump_internal_function (lf *file, + gen_entry *table, + function_entry * function, void *data) +{ + if (function->is_internal) + { + lf_printf (file, "\n"); + lf_print__line_ref (file, function->line); + lf_indent (file, -1); + print_function_name (file, + function->name, + NULL, + (options.gen.icache + ? function_name_prefix_icache + : function_name_prefix_semantics)); + lf_printf (file, ":\n"); + lf_indent (file, +1); + lf_printf (file, "{\n"); + lf_indent (file, +2); + lf_printf (file, "const unsigned_word cia = nia;\n"); + table_print_code (file, function->code); + lf_print__internal_ref (file); + print_sim_engine_abort (file, "Internal function must longjump"); + lf_indent (file, -2); + lf_printf (file, "}\n"); + } +} +#endif + + + +#if 0 +static void +print_jump_until_stop_body (lf *file, + insn_table *table, cache_table * cache_rules) +{ + lf_printf (file, "{\n"); + lf_indent (file, +2); + lf_putstr (file, "jmp_buf halt;\n"); + lf_putstr (file, "jmp_buf restart;\n"); + lf_putstr (file, "sim_cpu *cpu = NULL;\n"); + lf_putstr (file, "unsigned_word nia = -1;\n"); + lf_putstr (file, "instruction_word instruction = 0;\n"); + if ((code & generate_with_icache)) + { + lf_putstr (file, "idecode_cache *cache_entry = NULL;\n"); + } + if (generate_smp) + { + lf_putstr (file, "int current_cpu = -1;\n"); + } + + /* all the switches and tables - they know about jumping */ + print_idecode_lookups (file, table, cache_rules); + + /* start the simulation up */ + if ((code & generate_with_icache)) + { + lf_putstr (file, "\n"); + lf_putstr (file, "{\n"); + lf_putstr (file, " int cpu_nr;\n"); + lf_putstr (file, " for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n"); + lf_putstr (file, " cpu_flush_icache(cpus[cpu_nr]);\n"); + lf_putstr (file, "}\n"); + } + + lf_putstr (file, "\n"); + lf_putstr (file, "psim_set_halt_and_restart(system, &halt, &restart);\n"); + + lf_putstr (file, "\n"); + lf_putstr (file, "if (setjmp(halt))\n"); + lf_putstr (file, " return;\n"); + + lf_putstr (file, "\n"); + lf_putstr (file, "setjmp(restart);\n"); + + lf_putstr (file, "\n"); + if (!generate_smp) + { + lf_putstr (file, "cpu = cpus[0];\n"); + lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n"); + } + else + { + lf_putstr (file, "current_cpu = psim_last_cpu(system);\n"); + } + + if (!(code & generate_with_icache)) + { + lf_printf (file, "\n"); + lf_indent (file, -1); + lf_printf (file, "idecode:\n"); + lf_indent (file, +1); + } + + print_jump (file, 0 /*is_tail */ ); + + if ((code & generate_with_icache)) + { + lf_indent (file, -1); + lf_printf (file, "cache_miss:\n"); + lf_indent (file, +1); + } + + lf_putstr (file, "instruction\n"); + lf_putstr (file, " = vm_instruction_map_read(cpu_instruction_map(cpu),\n"); + lf_putstr (file, " cpu, nia);\n"); + print_idecode_body (file, table, "/*IGORE*/"); + + /* print out a table of all the internals functions */ + insn_table_traverse_function (table, + file, NULL, print_jump_internal_function); + + /* print out a table of all the instructions */ + if (generate_expanded_instructions) + insn_table_traverse_tree (table, file, cache_rules, 1, NULL, /* start */ + print_jump_definition, /* leaf */ + NULL, /* end */ + NULL); /* padding */ + else + insn_table_traverse_insn (table, + file, cache_rules, print_jump_definition); + lf_indent (file, -2); + lf_printf (file, "}\n"); +} +#endif + +/****************************************************************/ + + + +/* Output code to do any final checks on the decoded instruction. + This includes things like verifying any on decoded fields have the + correct value and checking that (for floating point) floating point + hardware isn't disabled */ + +void +print_idecode_validate (lf *file, + insn_entry * instruction, insn_opcodes *opcode_paths) +{ + /* Validate: unchecked instruction fields + + If any constant fields in the instruction were not checked by the + idecode tables, output code to check that they have the correct + value here */ + { + int nr_checks = 0; + int word_nr; + lf_printf (file, "\n"); + lf_indent_suppress (file); + lf_printf (file, "#if defined (WITH_RESERVED_BITS)\n"); + lf_printf (file, "/* validate: "); + print_insn_words (file, instruction); + lf_printf (file, " */\n"); + for (word_nr = 0; word_nr < instruction->nr_words; word_nr++) + { + insn_uint check_mask = 0; + insn_uint check_val = 0; + insn_word_entry *word = instruction->word[word_nr]; + int bit_nr; + + /* form check_mask/check_val containing what needs to be checked + in the instruction */ + for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++) + { + insn_bit_entry *bit = word->bit[bit_nr]; + insn_field_entry *field = bit->field; + + /* Make space for the next bit */ + check_mask <<= 1; + check_val <<= 1; + + /* Only need to validate constant (and reserved) + bits. Skip any others */ + if (field->type != insn_field_int + && field->type != insn_field_reserved) + continue; + + /* Look through the list of opcode paths that lead to this + instruction. See if any have failed to check the + relevant bit */ + if (opcode_paths != NULL) + { + insn_opcodes *entry; + for (entry = opcode_paths; entry != NULL; entry = entry->next) + { + opcode_field *opcode; + for (opcode = entry->opcode; + opcode != NULL; opcode = opcode->parent) + { + if (opcode->word_nr == word_nr + && opcode->first <= bit_nr + && opcode->last >= bit_nr) + /* we've decoded on this bit */ + break; + } + if (opcode == NULL) + /* the bit wasn't decoded on */ + break; + } + if (entry == NULL) + /* all the opcode paths decoded on BIT_NR, no need + to check it */ + continue; + } + + check_mask |= 1; + check_val |= bit->value; + } + + /* if any bits not checked by opcode tables, output code to check them */ + if (check_mask) + { + if (nr_checks == 0) + { + lf_printf (file, "if (WITH_RESERVED_BITS)\n"); + lf_printf (file, " {\n"); + lf_indent (file, +4); + } + nr_checks++; + if (options.insn_bit_size > 32) + { + lf_printf (file, "if ((instruction_%d\n", word_nr); + lf_printf (file, " & UNSIGNED64 (0x%08lx%08lx))\n", + (unsigned long) (check_mask >> 32), + (unsigned long) (check_mask)); + lf_printf (file, " != UNSIGNED64 (0x%08lx%08lx))\n", + (unsigned long) (check_val >> 32), + (unsigned long) (check_val)); + } + else + { + lf_printf (file, + "if ((instruction_%d & 0x%08lx) != 0x%08lx)\n", + word_nr, (unsigned long) (check_mask), + (unsigned long) (check_val)); + } + lf_indent (file, +2); + print_idecode_invalid (file, "return", invalid_illegal); + lf_indent (file, -2); + } + } + if (nr_checks > 0) + { + lf_indent (file, -4); + lf_printf (file, " }\n"); + } + lf_indent_suppress (file); + lf_printf (file, "#endif\n"); + } + + /* Validate: Floating Point hardware + + If the simulator is being built with out floating point hardware + (different to it being disabled in the MSR) then floating point + instructions are invalid */ + { + if (filter_is_member (instruction->flags, "f")) + { + lf_printf (file, "\n"); + lf_indent_suppress (file); + lf_printf (file, "#if defined(CURRENT_FLOATING_POINT)\n"); + lf_printf (file, "/* Validate: FP hardware exists */\n"); + lf_printf (file, + "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n"); + lf_indent (file, +2); + print_idecode_invalid (file, "return", invalid_illegal); + lf_indent (file, -2); + lf_printf (file, "}\n"); + lf_indent_suppress (file); + lf_printf (file, "#endif\n"); + } + } + + /* Validate: Floating Point available + + If floating point is not available, we enter a floating point + unavailable interrupt into the cache instead of the instruction + proper. + + The PowerPC spec requires a CSI after MSR[FP] is changed and when + ever a CSI occures we flush the instruction cache. */ + + { + if (filter_is_member (instruction->flags, "f")) + { + lf_printf (file, "\n"); + lf_indent_suppress (file); + lf_printf (file, "#if defined(IS_FP_AVAILABLE)\n"); + lf_printf (file, "/* Validate: FP available according to cpu */\n"); + lf_printf (file, "if (!IS_FP_AVAILABLE) {\n"); + lf_indent (file, +2); + print_idecode_invalid (file, "return", invalid_fp_unavailable); + lf_indent (file, -2); + lf_printf (file, "}\n"); + lf_indent_suppress (file); + lf_printf (file, "#endif\n"); + } + } + + /* Validate: Validate Instruction in correct slot + + Some architectures place restrictions on the slot that an + instruction can be issued in */ + + { + if (filter_is_member (instruction->options, "s") + || options.gen.slot_verification) + { + lf_printf (file, "\n"); + lf_indent_suppress (file); + lf_printf (file, "#if defined(IS_WRONG_SLOT)\n"); + lf_printf (file, + "/* Validate: Instruction issued in correct slot */\n"); + lf_printf (file, "if (IS_WRONG_SLOT) {\n"); + lf_indent (file, +2); + print_idecode_invalid (file, "return", invalid_wrong_slot); + lf_indent (file, -2); + lf_printf (file, "}\n"); + lf_indent_suppress (file); + lf_printf (file, "#endif\n"); + } + } + +} + + +/****************************************************************/ + + +void +print_idecode_issue_function_header (lf *file, + const char *processor, + function_decl_type decl_type, + int nr_prefetched_words) +{ + int indent; + lf_printf (file, "\n"); + switch (decl_type) + { + case is_function_declaration: + lf_print__function_type_function (file, print_semantic_function_type, + "INLINE_IDECODE", " "); + break; + case is_function_definition: + lf_print__function_type_function (file, print_semantic_function_type, + "INLINE_IDECODE", "\n"); + break; + case is_function_variable: + print_semantic_function_type (file); + lf_printf (file, " (*"); + break; + } + indent = print_function_name (file, + "issue", + NULL, + processor, + NULL, function_name_prefix_idecode); + switch (decl_type) + { + case is_function_definition: + indent += lf_printf (file, " ("); + break; + case is_function_declaration: + lf_putstr (file, "\n("); + indent = 1; + break; + case is_function_variable: + lf_putstr (file, ")\n("); + indent = 1; + break; + } + lf_indent (file, +indent); + print_semantic_function_formal (file, nr_prefetched_words); + lf_putstr (file, ")"); + lf_indent (file, -indent); + switch (decl_type) + { + case is_function_definition: + lf_printf (file, "\n"); + break; + case is_function_declaration: + case is_function_variable: + lf_putstr (file, ";\n"); + break; + } +} + + + +void +print_idecode_globals (lf *file) +{ + lf_printf (file, "enum {\n"); + lf_printf (file, " /* greater or equal to zero => table */\n"); + lf_printf (file, " function_entry = -1,\n"); + lf_printf (file, " boolean_entry = -2,\n"); + lf_printf (file, "};\n"); + lf_printf (file, "\n"); + lf_printf (file, "typedef struct _idecode_table_entry {\n"); + lf_printf (file, " int shift;\n"); + lf_printf (file, " unsigned%d mask;\n", options.insn_bit_size); + lf_printf (file, " unsigned%d value;\n", options.insn_bit_size); + lf_printf (file, " void *function_or_table;\n"); + lf_printf (file, "} idecode_table_entry;\n"); +}
gen-idecode.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: lf.h =================================================================== --- lf.h (nonexistent) +++ lf.h (revision 841) @@ -0,0 +1,115 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + + +/* LF: Line Numbered Output Stream */ + +typedef struct _lf lf; + +typedef enum +{ + lf_is_h, + lf_is_c, + lf_is_text, +} +lf_file_type; + + +typedef enum +{ + lf_include_references, + lf_omit_references, +} +lf_file_references; + + +/* Open the file NAME for writing ("-" for stdout). Use REAL_NAME + when refering to the opened file. Line number information (in the + output) can be suppressed with FILE_REFERENCES == + LF_OMIT_REFERENCES. TYPE is to determine the formatting of some of + the print messages below. */ + +extern lf *lf_open + (char *name, + char *real_name, + lf_file_references file_references, + lf_file_type type, const char *program); + +extern void lf_close (lf *file); + + +/* Basic output functions */ + +extern int lf_write (lf *file, const char *string, int len); + +extern int lf_putchr (lf *file, const char ch); + +extern int lf_putstr (lf *file, const char *string); + +extern int lf_putint (lf *file, int decimal); + +extern int lf_putbin (lf *file, int decimal, int width); + +extern int lf_printf + (lf *file, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); + + +/* Indentation control. + + lf_indent_suppress suppresses indentation on the next line (current + line if that has not yet been started) */ + +extern void lf_indent_suppress (lf *file); + +extern void lf_indent (lf *file, int delta); + + +/* Print generic text: */ + + +extern int lf_print__gnu_copyleft (lf *file); + +extern int lf_print__file_start (lf *file); + +extern int lf_print__this_file_is_empty (lf *file, const char *reason); + +extern int lf_print__file_finish (lf *file); + +extern int lf_print__internal_ref (lf *file); + +extern int lf_print__external_ref + (lf *file, int line_nr, const char *file_name); + +extern int lf_print__line_ref (lf *file, line_ref *line); + +extern int lf_print__ucase_filename (lf *file); + +extern int lf_print__function_type + (lf *file, + const char *type, const char *prefix, const char *trailing_space); + +typedef int print_function (lf *file); + +extern int lf_print__function_type_function + (lf *file, + print_function * print_type, + const char *prefix, const char *trailing_space);
lf.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: ChangeLog =================================================================== --- ChangeLog (nonexistent) +++ ChangeLog (revision 841) @@ -0,0 +1,1138 @@ +2009-08-22 Ralf Wildenhues + + * config.in: Regenerate. + * configure: Likewise. + + * configure: Regenerate. + +2009-07-30 Ralf Wildenhues + + * Makefile.in (datarootdir): New variable. + +2008-08-28 Joel Brobecker + + * compare_igen_models: Change license to GPL version 3. + +2007-08-27 Joel Brobecker + + * lf.c (lf_print__gnu_copyleft): Change license to GPL version 3. + +2006-12-21 Hans-Peter Nilsson + + * acconfig.h: Remove. + * config.in: Regenerate. + +2005-01-11 Andrew Cagney + + * configure.ac: Delete AC_CONFIG_AUX_DIR. + * configure: Re-generate. + +2005-01-07 Andrew Cagney + + * configure.ac: Rename configure.in, require autoconf 2.59. + * configure: Re-generate. + +2003-05-03 Chris Demetriou + + * compare_igen_models: Tweak attribution slightly. + +2002-11-22 Andrew Cagney + + * gen.c (name_cmp): Rename format_name_cmp. + (insn_list_insert): When a merge, compare the format name and + instruction name. Add trace messages. + +2002-11-21 Andrew Cagney + + * filter.c: Re-indent. + * filter.h, filter_host.h, gen-engine.c, gen-engine.h: Ditto. + * gen-icache.c, gen-icache.h, gen-idecode.c: Ditto. + * gen-idecode.h, gen-itable.c, gen-itable.h: Ditto. + * gen-model.c, gen-model.h, gen-semantics.c: Ditto. + * gen-semantics.h, gen-support.c, gen-support.h: Ditto. + * gen.c, gen.h, igen.c, igen.h, ld-cache.c, ld-cache.h: Ditto. + * ld-decode.c, ld-decode.h, ld-insn.c, ld-insn.h, lf.c: Ditto. + * lf.h, misc.c, misc.h, table.c, table.h: Ditto. + +2002-11-21 Andrew Cagney + + * Makefile.in: Update copyright. IGEN contributed to the FSF. + * filter.c, filter.h, filter_host.c, filter_host.h: Ditto. + * gen-engine.c, gen-engine.h, gen-icache.c, gen-icache.h: Ditto. + * gen-idecode.c, gen-idecode.h, gen-itable.c: Ditto. + * gen-itable.h, gen-model.c, gen-model.h, gen-semantics.c: Ditto. + * gen-semantics.h, gen-support.c, gen-support.h, gen.c: Ditto. + * gen.h, igen.c, igen.h, ld-cache.c, ld-cache.h: Ditto. + * ld-decode.c, ld-decode.h, ld-insn.c, ld-insn.h, lf.c: Ditto. + * lf.h, misc.c, misc.h, table.c, table.h: Ditto. + +2002-11-06 Richard Sandiford + + * gen-engine.c (print_engine_issue_prefix_hook): Don't add the + global prefix to ENGINE_ISSUE_PREFIX_HOOK. + (print_engine_issue_postfix_hook): Likewise ENGINE_ISSUE_POSTFIX_HOOK. + +2002-08-28 Dave Brolley + + * gen-support.c (gen_support_h): Generate + '#define semantic_illegal _semantic_illegal'. + +2002-08-22 Chris Demetriou + + * compare_igen_models: New script. + +2002-06-17 Andrew Cagney + + * gen.c (gen_entry_expand_opcode): Initialize ``value'' to -1 and + ``t'' to NULL. + * igen.c (main): Add default case to switch. + * gen-icache.c (print_icache_extraction): Ditto. + +2002-06-17 Andrew Cagney + + * Makefile.in (BUILD_CFLAGS): Remove -O0. + +2002-06-16 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +2002-06-03 Richard Henderson + + * gen-engine.c (print_run_body): Avoid multi-line strings. + * lf.c (lf_print__gnu_copyleft): Likewise. + +2002-05-01 Chris Demetriou + + * igen.c: Use 'deprecated' rather than 'depreciated.' + +2002-03-23 Andrew Cagney + + * gen.c (format_name_cmp): New function. + (insn_list_insert): Use the instruction field name as an + additional key. Different field names indicate different + semantics. + +2002-03-07 Chris Demetriou + + * igen.c (print_itrace_format): Add support for a new "%#lx" format. + +Tue May 23 21:39:23 2000 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +2000-04-12 Frank Ch. Eigler + + * gen-semantics.c (print_semantic_body): Use GPR_CLEAR(N) instead + of GPR_SET(N,0) for gen-zero-rN. + +Thu Sep 2 18:15:53 1999 Andrew Cagney + + * Makefile.in (SIM_WARNINGS): Replace this with. + (IGEN_WERROR_CFLAGS, IGEN_WARN_CFLAGS, WERROR_CFLAGS, + WARN_CFLAGS): With these. + (BUILD_CFLAGS): Update. + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +1999-05-08 Felix Lee + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Fri Dec 4 15:14:09 1998 Andrew Cagney + + * igen.c (main): Fix -Pitable=. + + * gen-engine.c (print_run_body): Prefix instruction_address. + +Wed Oct 28 18:12:43 1998 Andrew Cagney + + * Makefile.in (SIM_WARNINGS): Update to match ../common/aclocal.m4 + changes. + +Wed Aug 12 10:55:28 1998 Frank Ch. Eigler + + * gen-icache.c (print_icache_extraction): #undef a generated + symbol before #define'ing it, to remove conflict with system + macros. + +Wed Jul 29 10:07:27 1998 Andrew Cagney + + * gen.c (gen_entry_expand_opcode): For conditional, fields. Fix + the extraction of the value from its source - both table and bit + cases were wrong. + +Tue Jul 28 11:19:43 1998 Andrew Cagney + + * ld-insn.c (parse_insn_word): For constant conditional strings, + encode their bit value. + + * ld-insn.c (parse_insn_word, parse_insn_words): Allow conditional + operands to refer to fields in earlier instruction words. + + * gen.c (sub_val): Replace field argument with val_last_pos. + (gen_entry_expand_opcode): Look in previous tables for a value for + a conditional field as well as the bits from the current table. + (insn_list_insert): Add sort key of instructions where + their operand fields have different conditionals. + (insn_field_cmp): New function. + +Sun Apr 26 15:31:55 1998 Tom Tromey + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Sun Apr 26 15:20:08 1998 Tom Tromey + + * acconfig.h: New file. + * configure.in: Reverted change of Apr 24; use sinclude again. + +Fri Apr 24 14:16:40 1998 Tom Tromey + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Fri Apr 24 11:19:33 1998 Tom Tromey + + * configure.in: Don't call sinclude. + +Fri Apr 24 19:45:00 1998 Andrew Cagney + + * gen-icache.c (print_icache_extraction): Do not type cast + pointers. + + * ld-insn.c (load_insn_table): Terminate error with NL. + + * gen.c (insns_bit_useless): Perform unsigned bit comparisons. + + * filter.c (is_filtered_out, filter_parse): Pacify GCC, len is + unsigned. + +Wed Apr 22 14:27:39 1998 Michael Meissner + + * configure: Reconfigure to pick up ../common/aclocal.m4 changes + to suppress inlining by default. + +Tue Apr 21 01:37:54 1998 Andrew Cagney + + * gen-icache.c (print_icache_extraction): When generating #define + force the expression to the correct type. + +Thu Apr 16 08:50:29 1998 Andrew Cagney + + * misc.c (name2i): strlen returns an unsigned. + +Tue Apr 14 19:04:28 1998 Andrew Cagney + + * igen.h (struct igen_warn_options): Add unimplemented option. + * igen.c (main): Update + + * ld-insn.c (load_insn_table): Report unimplemented functions. + +Tue Apr 14 10:57:26 1998 Andrew Cagney + + * ld-insn.c (parse_insn_word): Treat `!' and `=' as valid + separator tokens when parsing a conditional. + + * igen.h (main): Add option -S so that suffix can be specified. + +Tue Apr 14 08:44:53 1998 Andrew Cagney + + * igen.h (struct igen_trace_options): Add members insn_expansion + and insn_insertion. + + * igen.c (main): Add options -Gtrace-insn-expansion, + -Gtrace-insn-insertion and -Gtrace-all. + + * gen.c (gen_entry_expand_insns): Trace each instruction as it is + selected for expansion. + (gen_entry_expand_opcode): Trace each expanded instruction as it + is inserted into the table. + +Mon Apr 13 19:21:47 1998 Andrew Cagney + + * ld-insn.c (parse_insn_word): Parse conditional operators. + (parse_insn_word): Verify field conditionals. + + * ld-insn.h: Extend syntax to allow macros and field equality. + (struct insn_field_cond): Rename insn_field_exclusion, add type. + + * gen.c (gen_entry_expand_opcode): Check type of conditional. + (insns_bit_useless): Ditto. + + * ld-insn.c (parse_macro_record): New function. + +Mon Apr 13 22:37:47 1998 Andrew Cagney + + * ld-insn.h (enum insn_field_type): Add insn_field_invalid. + + * ld-insn.c (parse_insn_word): Check instruction field type + correctly initialized. + (print_insn_words): Ditto. + (insn_field_type_to_str): Ditto. + (dump_insn_field): Ditto. + + * gen.c (insns_bit_useless): Ditto. + +Fri Apr 3 18:08:16 1998 Andrew Cagney + + * gen.h, igen.c (print_include_inline, print_includes, + print_includes): New functions. Generate include list. For for + semantics et.al. generate CPP code to inline when + C_REVEALS_MODULE_P. + + * igen.c (gen_semantics_c): Call print_includes. + * gen-engine.c (gen_engine_c): Ditto. + +Sat Apr 4 21:09:11 1998 Andrew Cagney + + * igen.h: (struct _igen_name_option): Replace with struct + igen_module_option. Contains both module prefix and suffix. + (INIT_OPTIONS): Initialize. + + * igen.c (main): Update -P option to fill in full module info. + (gen-engine.c, gen-icache.c, gen-itable.c, gen-semantics.c, + gen-support.c): Update. + +Sat Apr 4 02:15:35 1998 Andrew Cagney + + * igen.c (print_itrace): Use TRACE_ANY_P macro to determine if any + tracing is needed. + +Thu Mar 26 20:51:23 1998 Stu Grossman + + * table.c (table_push): Redo, using stdio. Fixes NT native + problem with => translation... + +Tue Mar 24 23:30:07 1998 Andrew Cagney + + * gen-engine.c (print_run_body): Re-extract the CIA after + processing any events. + +Tue Mar 24 17:46:08 1998 Stu Grossman + + * Makefile.in: Get SHELL from configure. + * configure: Regenerate with autoconf 2.12.1 to fix shell issues for + NT native builds. + +Mon Mar 16 12:51:31 1998 Andrew Cagney + + * igen.c: Pass sim_cia to trace_prefix. + +Thu Feb 26 19:25:02 1998 Andrew Cagney + + * ld-insn.c (parse_function_record): Check models are valid. + (parse_function_record): Only discard function when no model is + common. + +Tue Feb 24 01:42:03 1998 Andrew Cagney + + * gen-engine.c (print_run_body): Always wrap generated idecode + body in ENGINE_ISSUE_PREFIX_HOOK / ENGINE_ISSUE_POSTFIX_HOOK. + +Fri Feb 20 16:22:10 1998 Andrew Cagney + + * ld-insn.c (parse_function_record): When -Wnodiscard, suppress + discarded function warning. + + * igen.c (main): Clarify -Wnodiscard. + + * ld-insn.c (parse_function_record): For functions, allow use of + instruction style function model records + + * ld-insn.h (nr_function_model_fields): Define. + +Tue Feb 17 16:36:27 1998 Andrew Cagney + + * igen.c (print_itrace_prefix): Generate call to trace_prefix + instead of trace_one_insn. + (print_itrace): Generate trace_prefix call if any tracing enabled, + (print_itrace): Nest generated call to trace_generic inside + conditional for any tracing enabled. + (print_itrace_prefix): Do not pass PHASE to trace_prefix. + +Tue Feb 3 14:00:32 1998 Andrew Cagney + + * gen-engine.c (print_run_body): Add bitsize suffix to IMEM macro. + * gen-icache.c (print_icache_body): Ditto. + * gen-idecode.c (print_idecode_ifetch): Ditto. + + * gen-icache.c (print_icache_body): Mark successive instruction + words as unused. + + * ld-insn.c (parse_insn_word): Only report insn-width problems + when warning enabled. + + * igen.h: Add flag for warning about invalid instruction widths. + * igen.c: Parse -Wwidth option. + + * gen-support.c (gen_support_h): Map instruction_word onto + _instruction_word when needed. + (print_support_function_name): Use support prefix. + (gen_support_h): Ditto for _idecode_issue. + +Sun Feb 1 11:08:48 1998 Andrew Cagney + + * gen-support.c (gen_support_h): Generate new macro CPU_. + +Sat Jan 31 14:50:27 1998 Andrew Cagney + + * gen-engine.c (gen_engine_h): Don't assume a model is present. + (gen_engine_c): Ditto. + + * igen.c (gen_run_c): Ditto. + + * gen-engine.c (print_run_body): Use CIA_GET & CIA_SET instead of + CPU_CIA. Parameterize with CPU argument. + +Fri Jan 30 09:09:39 1998 Andrew Cagney + + * gen.h (struct _gen_list): Replace processor with model. + + * igen.c (gen_idecode_h): Update. + (gen_run_c): For generated switch, use model->full_name. + + * gen.c (print_gen_entry_path): Ditto. + (make_table): Ditto. + (gen_entry_expand_insns): Ditto. + (make_gen_tables): Ditto. + + * igen.c (gen_run_c): Add extra argument `nr_cpus' to generated + function sim_engine_run. Pass argument on to engine_run. + + * gen-engine.c (print_engine_run_function_header): Add extra + argument `nr_cpus' to generated function engine_run. + (print_run_body): Fix SMP case. + + * gen-support.c (support_c_function): Call sim_engine_abort when + internal function fails to long jump. + +Wed Jan 21 18:00:22 1998 Andrew Cagney + + * gen-semantics.c (print_semantic_body): Use GPR_SET to zero + hardwired register. + +Wed Dec 17 14:49:03 1997 Jeffrey A Law (law@cygnus.com) + + * gen-semantics.c (print_semantic_body): Fix handling of + hardwired zero register. + +Tue Dec 9 12:45:00 1997 Andrew Cagney + + * igen.h (struct _igen_gen_options): Add member default_model. + + * igen.c (gen_run_c): Default to the first machine in the + multi-sim list. + (main): Add MODEL parameter to gen-multi-sim option. + + * gen.h (function_decl_type): Declare enum. + + * gen-engine.c (print_engine_run_function_header), gen-engine.h: + Make global, pass function_decl_type as argument. + (gen_engine_h, gen_engine_c): Update call. + + * gen-idecode.c (print_idecode_issue_function_header), + gen-idecode.h: Pass function_decl_type as argument. + + * igen.c (gen_idecode_h): For multi-sim, delcare global variable + idecode_issue. + + * igen.c (gen_run_c): For multi-sim, initialize globals + idecode_issue and engine_run. + +Fri Nov 14 10:51:44 1997 Andrew Cagney + + * ld-insn.c (parse_insn_model_record): Allow multiple model names + to be specified in a single instruction model record. + (dump_insn_model_entry): Update. + + * ld-insn.h (struct _insn_model_entry): Replace member name with + the filter names. Document syntax change. + +Wed Nov 12 15:45:40 1997 Andrew Cagney + + * gen-engine.c (print_run_body): Add hooks for adding code before + and after an instruction has been issued. + +1997-11-04 Brendan Kehoe + + * gen-idecode.c (print_jump_until_stop_body): Use `#if 0' instead of + `#ifdef 0' around this. + +Tue Nov 4 08:18:29 1997 Michael Meissner + + * ld-decode.c (load_decode_table): Don't assume NULL is an integer + constant. + +Wed Oct 29 13:17:17 1997 Andrew Cagney + + * ld-insn.h: Document mnemonic string format. + +Tue Oct 28 10:50:35 1997 Andrew Cagney + + * gen-icache.c (print_icache_extraction): Force result of atol to + unsigned. + + * ld-insn.c (parse_function_record): Separate handling of old and + ney fynction records. + (load_insn_table): For %s record, hack function name & type after + it has been parsed. + + * filter.h (filter_is_subset): Reverse argument names, wrong + order. + + * ld-insn.c (load_insn_table): Move include code to. + (parse_include_record): New function. Check for filtering of + include statement by both flags and models. + (load_insn_table): Check for model filtering of cache and model + records. + (parse_model_data_record): Check for model & flag filtering of + model data records. + (parse_function_record): Check for model & flag filtering of + function records. + + * ld-insn.h: Define record_filter_models_field. Add filter-models + field to all but instruction records. + (struct _function_entry, struct _cache_entry): Add models field. + (nr_function_fields): Make parm field mandatory. + +Mon Oct 27 15:14:26 1997 Andrew Cagney + + * igen.c (main): Change -I option to -I. Add optional + size to -Ggen-icache option. Add -Gno-... support. + + * igen.h (struct _igen_options): Add include field. + + * ld-insn.c (enum insn_record_type, insn_type_map): Add + include_record. + (load_insn_table): Call table_push when include record. + + * table.c (struct _open table, struct table): Make table object an + indirect ptr to the current table file. + (current_line, new_table_entry, next_line): Make file arg type + open_table. + (table_open): Use table_push. + (table_read): Point variable file at current table, at eof, pop + last open table. + + * table.h, table.c (table_push): New function. + +Thu Oct 16 11:03:27 1997 Andrew Cagney + + * gen-semantics.c (print_semantic_body): Use CIA not + cia.ip. Escape newlines at end of generated call to + sim_engine_abort. + +Tue Oct 14 11:13:27 1997 Andrew Cagney + + * igen.c (print_itrace): Output line-ref to igen source file when + generating trace statements. + (print_itrace_prefix, print_itrace_format): Escape newline at end + of each line of generated call to trace function. + +Mon Oct 13 11:27:31 1997 Andrew Cagney + + * gen-support.c (gen_support_h): Generate #define NIA. Definition + dependant on gen-delayed-branch mode. + + * ld-insn.c (parse_insn_mnemonic_record): Check for opening and + closing double quote in mnemonic field. + (parse_option_record): Add gen-delayed-branch option. + +Wed Oct 8 13:10:16 1997 Andrew Cagney + + * gen.c (insn_list_insert): Missing \n in warning. + + * ld-insn.c (load_insn_table): Only notify of discarded + instrctions when warn.discard enabled. + + * igen.h: Add option.warn.discard, default enabled. + + * igen.c (main): Add -Wnodiscard option. + + * ld-insn.c (record_type): For old record type, check the number + of fields is correct. + (load_insn_table): Allow insn assembler and insn model records to + appear in any order. + (parse_insn_model_record): Rename from parse_insn_model_records. + Parse only one record. + (parse_insn_mnemonic_record): Rename from + parse_insn_mnemonic_records. Parse only one record. + +Tue Sep 23 15:52:06 1997 Felix Lee + + * gen-itable.c (gen_itable_h): [nr_itable_* + 1] to avoid + illegal zero-sized array. + (itable_print_set): likewise, avoid empty initializers. + +Mon Sep 22 18:49:07 1997 Felix Lee + + * configure.in: i386-windows is a cross, so don't expect + libiberty to be there. + * configure: updated. + +Fri Sep 19 10:36:30 1997 Andrew Cagney + + * igen.c (print_function_name): Put the format name after the + function / instruction name, not before. + (print_itrace): Better format trace code. + +Tue Sep 16 11:01:07 1997 Andrew Cagney + + * gen.c (insns_bit_useless): Don't treat string fields restricted + to a range of values as useless. + +Mon Sep 15 15:47:21 1997 Andrew Cagney + + * igen.c (gen_run_c): Handle non-multi-sim case. + + * gen-support.c (gen_support_h): Define SD_ - to replace _SD. + Define CIA from cia. + +Thu Sep 11 10:27:39 1997 Andrew Cagney + + * gen-semantics.c (print_semantic_body): Trace the instruction + after it has been validated. + (print_semantic_body): Count the instruction using sim-profile. + +Wed Sep 10 13:35:37 1997 Andrew Cagney + + * gen-itable.c (gen_itable_h): Collect summary info on instruction + table when traversing it. + (gen_itable_h): Output an enum defining the max size of each of + the itable string members. + +Tue Sep 9 03:30:26 1997 Andrew Cagney + + * igen.c (gen_run_c): New function. Generate sim_engine_run that + looks at the currently selected architecture. + + * gen-engine.c, gen-idecode.c: Add multi-sim support - generate + one engine per model. + + * gen-semantics.c, gen-icache.c gen-support.c: + Update. + + * ld-insn.h, ld-insn-h (load_insn_table): Rewrite. table.h only + returns a line at a time. Parse multi-word instructions. Add + multi-sim support. + + * table.h, table.c: Simplify. Only parse a single line at a time. + ld-insn can handle the rest. + + * filter.h, filter.c (filter_parse, filter_add, filter_is_subset, + filter_is_common, filter_is_member, filter_next): New filter + operations. + (dump_filter): Ditto. + + * gen.h, gen.c: New file. Takes the insn table and turns it into + a set of decode tables and semantic functions. + + * ld-insn.c: Copy generator code from here. + * gen.c: To here. + +Fri Aug 8 11:43:45 1997 Andrew Cagney + + * misc.h (NZALLOC): Allocate an N element array of TYPE. + + * table.h, table.c: Simplify table parser so that it only + understands colon delimited lines and code blocks. + (table_read): Parse '{' ... '}' as a code block. + (table_print_code): New function, print out a code block to file. + (main): Add suport for standalone testing. + + * ld-insn.h, ld-insn.c: + + +Mon Sep 1 11:41:12 1997 Andrew Cagney + + * gen-idecode.c (error_leaf_contains_multiple_insn): Make static. + (print_jump_definition, print_jump, print_jump_internal_function, + print_jump_insn, print_jump_until_stop_body): Delete, moved to + sim-engine.c + + * igen.c (print_itrace_format): Delete unused variable chp. + (gen-engine.h): Include. + + * table.c (current_file_name, current_line_entry, + current_line_entry): Make static. + +Wed Aug 6 12:31:17 1997 Andrew Cagney + + * configure.in: Define AR_FOR_BUILD, AR_FLAGS_FOR_BUILD, + RANLIB_FOR_BUILD and CFLAGS_FOR_BUILD. + * configure.in: Include simulator common/aclocal.m4. + * configure.in: Add --enable-sim-warnings option. + * configure: Re-generate. + + * Makefile.in: Use. + + * Makefile.in (tmp-filter): New rule. + (igen.o, tmp-table, tmp-ld-decode, tmp-ld-cache, tmp-ld-insn, + ld-decode.o, ld-cache.o, ld-insn.o): Fix dependencies. + + * gen.h, gen.c: New files. + + * Makefile.in (gen.o, tmp-gen): New rules, update all + dependencies. + +Tue Jun 24 11:46:45 1997 Andrew Cagney + + * ld-insn.c (load_insn_table): Accept %s as a function type. + +Thu Jun 5 17:14:32 1997 Andrew Cagney + + * igen.c (print_itrace_prefix): Move printing of insn prefix to + here. + (print_itrace_format): Drop printing of MY_NAME in instruction + trace. Printing of insn prefix moved. + (print_itrace): Ditto. + +Fri May 30 11:27:37 1997 Andrew Cagney + + * gen-icache.c (print_icache_function_header): Pass + table_line_entry instead of separate file and line. + + * table.c (table_entry_read): Set assembler source file/line-nr to + the current not initial file. + (table_entry_read): Fix line numbering of source files. + + table.h (table_line_entry): New structure. Exactly specifies a + source file/line-nr. + (table_*_entry): Add this to all. + + table.c (table_entry_print_cpp_line_nr): Change to use values from + a table_line_entry struct. + (table_entry_read): Save table_line_entry in all structures read. + + gen-icache.c, gen-support.c, gen-idecode.c, gen-semantics.c, + gen-model.c: Update all references. + +Thu May 29 10:29:57 1997 Andrew Cagney + + * igen.c (print_my_defines): Define MY_NAME - a string. For + MY_PREFIX, undefine the name of the function incase some dumb + header defined it. it. + (print_itrace): Use MY_NAME not MY_PREFIX. + + * lf.c (lf_write): New function write an N character buffer to the + file. + + * igen.c (print_itrace): When available, use the assembler to + print the insn-trace. + (print_itrace_prefix): New function, print first part of call to + print_one_insn. + (print_itrace_format): New function, print fmt argument for + print_one_insn. + + * table.c (table_entry_read): Save any assembler lines instead of + discarding them. + +Wed May 28 09:55:29 1997 Andrew Cagney + + * gen-icache.c (print_icache_body): Process immeds. + + * gen-semantics.c (print_semantic_body): When computing NIA, skip + any immed words that follow the instruction word. + + * ld-insn.c (parse_insn_format): Parse immeds appended to an + instruction. + + * igen.c (main): Allow any register to be specified as the zero + register. + (semantic_zero_reg): Global, index to zero register. + + * gen-semantics.c (print_semantic_body): Zero selected register. + +Tue May 27 14:12:32 1997 Andrew Cagney + + * igen.h: Stop options and code gen type bit masks overlaping. + +Fri May 23 12:01:08 1997 Andrew Cagney + + * gen-semantics.c (print_semantic_body): Incorrect test for + zero-r0 code. + +Fri May 16 14:32:31 1997 Andrew Cagney + + * gen-semantics.c (print_semantic_body): Use common sim-engine + interface. + +Fri May 16 11:48:30 1997 Andrew Cagney + + * gen-semantics.c (print_semantic_body): Add code to clear r0. + + * igen.c (main): Add new option zero-r0, which adds code to clear + GPR(0) each cycle. + +Wed May 7 12:31:30 1997 Andrew Cagney + + * igen.c (print_itrace): Fix so line-nr is passed to trace + function. + + * gen-idecode.c (print_idecode_validate): Correct FP code. + + * gen-support.c (gen_support_h): Always pass MY_INDEX to support + functions. + (print_support_function_name): Ditto. + +Tue May 6 06:12:04 1997 Mike Meissner + + * igen.c (print_itrace): Call trace_one_insn to trace + instructions, rather than doing it directly. + +Mon May 5 14:11:46 1997 Mike Meissner + + * gen-engine.c (engine_switch_leaf): Remove extra %s. + (print_engine_floating_point_unavailable): Wrap in #ifdef + UNUSED/#endif, until somebody uses it. + + * gen-idecode.c (error_leaf_contains_multiple_insn): Remove unused + variable. + (print_jump_until_stop_body): Wrap in #ifdef UNUSED/#endif, until + somebody uses it. + (print_idecode_validate): Use long formats to print long values. + + * gen-semantics.c (print_idecode_invalid): Set name to "unknown" + if we get an unexpected type. + +Fri May 2 13:28:06 1997 Andrew Cagney + + * igen.c (print_itrace): Pass SD as well as CPU to calls to + trace_printf. + + * gen-support.c (gen_support_h): Always pass sim_cia cia to + support functions. + (print_support_function_name): Ditto. + +Wed Apr 30 17:35:51 1997 Andrew Cagney + + * gen-support.c (support_c_function): Remove unnecessary memset of + cia. + * gen-semantics.c (print_semantic_body): Wasn't closing + generated comment. + +Tue Apr 29 11:11:12 1997 Andrew Cagney + + * ld-insn.c (load_insn_table): Report instructions that do not + have at least a format and name. + (insn_table_find_opcode_field): Check progress is being made. + + * gen-support.c (support_c_function): Report empty function body. + +Thu Apr 24 11:43:45 1997 Andrew Cagney + + * ld-insn.c (insn_table_expand_opcode): Allow reserved fields to + be broken up. + (insn_table_expand_insns): Allow special rules to apply to groups + of instructions when all members of the group match the special + mask/value. + + * gen-semantics.c (print_c_semantic): Ditto. + * igen.c (print_semantic_function_formal): Ditto. + (print_semantic_function_type): Ditto. + * igen.c (print_icache_function_formal): Ditto. + * gen-idecode.c (print_idecode_issue_function_body): Ditto. + + * gen-idecode.c (gen_idecode_h): Prepend the global_prefix to the + instruction_address type. + + * gen-semantics.c (print_semantic_body): Call cpu_error when an + unimplemented instruction is encountered - gives the interpreter + the chance to stop correctly. + +Wed Apr 23 20:06:36 1997 Andrew Cagney + + * igen.c (print_function_name): Allow dot's in instruction names. + +Tue Apr 22 21:46:28 1997 Andrew Cagney + + * igen.c (main), igen.h: Support new option - delayed-branch - + generate code to drive a delayed branch processor. + + * gen-idecode.c (gen_idecode_h): Define instruction_address type. + + * igen.c (print_icache_function_formal): Replace address_word with + instruction_address. + (print_semantic_function_formal): Ditto. + (print_semantic_function_type): Ditto. + * gen-idecode.c (print_idecode_issue_function_body): Ditto. + + * gen-semantics.c (print_semantic_body): Ditto. + (print_c_semantic): Ditto. + + * gen-support.c (support_c_function): Return a zeroed CIA instead + of just zero - works with any cia type. + + * igen.c (print_itrace): For delayed branch case, print just the + current instruction. + +Thu Apr 17 07:02:33 1997 Doug Evans + + * igen.c (print_itrace): Use TRACE_FOO_P and trace_printf. + +Tue Apr 15 15:20:31 1997 Ian Lance Taylor + + * Makefile.in (INSTALL): Set to @INSTALL@. + (INSTALL_XFORM, INSTALL_XFORM1): Remove. + +Mon Apr 14 16:29:34 1997 Ian Lance Taylor + + * Makefile.in (INSTALL): Change install.sh to install-sh. + +Wed Apr 2 18:51:20 1997 Doug Evans + + * gen-support.c (gen_support_c): sim-state.h renamed to sim-main.h. + * gen-idecode.c (gen_idecode_c): Likewise. + * igen.c (gen_semantics_c): Likewise. + +Mon Mar 24 10:10:08 1997 Andrew Cagney + + * gen-icache.c (print_icache_body): No longer define cpu/sd, + support.h now defines CPU/SD globally. + + * gen-model.c (gen_model_h): Ditto. + + * gen-idecode.c (print_idecode_issue_function_body): Ditto. + (print_jump): Ditto. + (print_jump_until_stop_body): Ditto. + (print_idecode_validate): Ditto. + + * gen-icache.c (print_icache_body): Ditto. + + * gen-semantics.c (print_semantic_body): Ditto. + + * igen.c (print_semantic_function_formal): Rename cpu to sim_cpu, + processor to cpu. + (print_icache_function_formal): Ditto. + + * gen-support.c (print_support_function_name): Include sd/cpu arg + in support function argument list. + (support_c_function): Generate code to cpu/sd from sd/cpu. + (gen_support_h): Define _SD the argument prefix for all support + functions. Define SD/CPU to determine sd/cpu from value of _SD + macro. + +Tue Mar 18 15:52:24 1997 Andrew Cagney + + * gen-support.c (gen_support_c): Update for renaming of engine to + sim-state. + + * igen.c: Ditto. + * gen-idecode.c (gen_idecode_c): Ditto. + +Mon Mar 17 15:17:07 1997 Andrew Cagney + + * ld-decode.c (load_decode_table): Rename slash to reserved. + (dump_decode_rule): Ditto. + + * ld-insn.c (parse_insn_format): Differentiate between a `/' - + reserved bit - and a `*' - wild card. + (parse_insn_format): Change is_slash to more informative reserved. + (dump_insn_field): Ditto. + (insn_field_is_constant): Ditto. + (insn_table_expand_opcode): Ditto. + + * gen-idecode.c (print_idecode_validate): Make check_mask and + check_val the correct integer size. + (print_idecode_validate): Fix reserved bit check for 64 bit + targets. + +Fri Mar 14 11:24:06 1997 Andrew Cagney + + * ld-insn.c (parse_insn_format): Accept '*' as an alternative of + `/' in bit fields. `/' denotes a wild bit. + +Fri Mar 7 18:20:38 1997 Andrew Cagney + + * igen.h, igen.c (main): New options. Control generation of + conditional issue and slot verification code. + +Fri Mar 7 18:17:25 1997 Andrew Cagney + + * gen-support.c (print_support_function_name): Prepend the global + name prefix when applicable. Provide #define to map the user + specified name the generated globaly unique one. + +Fri Mar 7 18:07:45 1997 Andrew Cagney + + * gen-idecode.c (print_idecode_validate): Wrap each of the checks + - reserved bits, floating point and slot validation - with a + #ifdef so that they are optional. + +Fri Mar 7 16:35:13 1997 Andrew Cagney + + * gen-idecode.c (error_leaf_contains_multiple_insn): New function + - report the error of a leaf node in the decision tree containing + several instructions. + (print_idecode_table_leaf): Detect a leaf with multiple instructions. + (print_idecode_switch_leaf): Ditto. + + * gen-semantics.h, gen-semantics.c (print_idecode_illegal, + print_idecode_invalid): Rename former to latter. Add argument so + that one function can generate all invalid instruction cases - + illegal, fp-unavailable, wrong-slot. + * gen-engine.c: Update. + + * gen-idecode.c: Use print_idecode_invalid to generate a function + call for cases when fp-unavailable and the slot is wrong. + + * gen-idecode.c (print_idecode_validate): New check, generate code + to verify that the instruction slot is correct. + + * igen.c (main): Simplify options. + +Wed Mar 5 09:55:55 1997 Andrew Cagney + + * igen.c (print_itrace): Remove source line reference for trace + code - let the user see the generated file. + (print_itrace): Print the trace code rather than reference a + macro. + +Tue Mar 4 17:31:55 1997 Andrew Cagney + + * igen.c (print_semantic_function_actual): Pass either the + processor - smp - or the engine - mono - into semantic functions. + Don't pass in both. + + * gen-icache.c (print_icache_body): Dependant on smp, derive + processor from engine or engine from processor, and hence ensuring + that both are defined in all semantic functions. + +Mon Mar 3 17:11:21 1997 Andrew Cagney + + * ld-insn.c (parse_insn_format): Make the width field optional. + If missing assume that the number of characters in the value + determines the number of bits in the field. + +Thu Feb 27 11:27:48 1997 Andrew Cagney + + * ld-insn.c (insn_table_expand_opcode): Replace assertion with + more useful error message. + +Tue Feb 25 16:43:27 1997 Andrew Cagney + + * misc.c (error): Output errors on stderr. + + * ld-insn.c (parse_insn_format): Skip any leading spaces. + Verify the width of instructions being parsed. + + * table.c (table_entry_read): Parse CPP's convention for + specifying original file name/line-nr. + +Wed Feb 19 12:30:28 1997 Andrew Cagney + + * ld-insn.c (parse_insn_format): Allow trailing spaces in + instruction fields. + + * Makefile.in: Create using ../ppc/Makefile.in as a starting + point. + * configure.in: Ditto vis ../ppc/configure.in + +Mon Feb 17 10:44:18 1997 Andrew Cagney + + * gen-support.c (gen_support_c): Always include engine.h instead + of cpu.h + * gen-idecode.c (gen_idecode_c): Ditto. + + * words.h (instruction_word): Remove instruction_word - now + generated by igen. + (address_word): New. Used by igen. + + * lf.c (lf_print_function_type_function): New, pass a function to + print out the type instead of a constant string. + + * igen.h, igen.c (print_semantic_function_formal, + SEMANTIC_FUNCTION_FORMAL): Relace macro with function. + (print_semantic_function_actual, SEMANTIC_FUNCTION_ACTUAL): Ditto. + (print_semantic_function_type, SEMANTIC_FUNCTION_TYPE): Ditto. + (print_icache_function_type, ICACHE_FUNCTION_TYPE): Ditto. + (print_icache_function_formal, ICACHE_FUNCTION_FORMAL): Ditto. + (print_icache_function_actual, ICACHE_FUNCTION_ACTUAL): Ditto. + * gen-idecode.c (print_idecode_table): Update. + (idecode_switch_leaf): Update. + (print_idecode_switch_function_header): Ditto. + (print_idecode_floating_point_unavailable): Ditto. + (print_idecode_issue_function_header): Ditto. + * igen.c (gen_icache_h): Ditto. + * gen-engine.c (print_engine_table): Ditto. + (engine_switch_leaf): Ditto. + * gen-support.c (print_support_function_name): Ditto. + * gen-semantics.c (print_semantic_function_header): Update. + Update. + * gen-icache.c (print_icache_function_header): Update. + (print_icache_function): Update. + (print_icache_internal_function_declaration): Update. + (print_icache_internal_function_definition): Update. + + * gen-idecode.c (gen_idecode_h): Drop including of idecode_*.h + files, will at some stage need to move it into support. + + * igen.h, igen.c (main): New option -e - generate a full + simulation engine. Previously this was the -d + option. + * gen-engine.h, gen-engine.c: Copies of gen-idecode.*. Will need + to clean these up so that that call upon the updated gen-idecode + code. + + * gen-idecode.h, gen-idecode.c: Prune out any code not relevant to + generating a decode table. + + * Makefile.in (igen): Add dependencies for new gen-engine.* files. + + * igen.h, igen.c (main): New option -M - Control what is returned + by semantic functions - -1/NIA vs CIA+N/NIA. Add + generate_semantic_returning_modified_nia_only to igen_code enum. + * gen-semantics.c (print_semantic_body): As an alternative, make + NIA == -1 instead of CIA+insn_size by default. + + * igen.h, igen.c (main, global_name_prefix, global_uname_prefix): + New option -P - Prepend all generated functions with the + specified prefix. + (gen_idecode_c): Adjust. + * gen-icache.c (print_icache_struct): Ditto. + * gen-support.c (gen_support_c): Ditto. + +Sun Feb 16 15:23:15 1997 Andrew Cagney + + * igen.c (main): Correct usage. Missleading message about ucase + options dumping internal tables. -F now includes rather then + excludes instructions. + + * misc.h, misc.c (a2i): Make 64bit. + + * ld-insn.h (max_insn_bit_size, default_insn_bit_size): Increase + max to 64bits, expect trouble. Make the default 32 bits. + * gen-idecode.c (print_idecode_table): Change EXTRACTED* + et.al. macro's to use the insn_bit_size instead of assuming 32 + bits. + * gen-icache.c (print_icache_extraction): Ditto. + * gen-idecode.c (idecode_switch_start): Ditto. + * gen-idecode.c (gen_idecode_c): Ditto + + * igen.h (insn_specifying_widths), igen.c (main): New option -W. + Indicates that the instruction field of the table is specifying + bit widths instead of bit offsets. + * ld-insn.c (parse_insn_format): Parse instruction fields + specifying widths. + + * misc.c (a2i): Allow binary numbers to be specified using the + syntax 0bNNNN. + * ld-insn.c: Allow such numbers to appear in the instruction + format. + + * table.c (table_entry_read): Make // a valid comment character. + (table_entry_read): Skip lines containing a leading " - these may + eventually be used in a disasembler. + +Fri Feb 14 15:23:15 1997 Andrew Cagney + + * filter.c, filter.h, gen-engine.c, gen-engine.h, gen-icache.c, + gen-icache.h, gen-idecode.c, gen-idecode.h, gen-itable.c, + gen-itable.h, gen-model.c, gen-model.h, gen-semantics.c, + gen-semantics.h, gen-support.c, gen-support.h, igen.c, igen.h, + ld-cache.c, ld-cache.h, ld-decode.c, ld-decode.h, ld-insn.c, + ld-insn.h, lf.c, lf.h, misc.c, misc.h, table.c, table.h: Copy in + from the ../ppc directory. + + * filter_host.c, filter_host.h: Copy in from the ../ppc directory + renaming from filter_filename.[hc]
ChangeLog Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen-idecode.h =================================================================== --- gen-idecode.h (nonexistent) +++ gen-idecode.h (revision 841) @@ -0,0 +1,43 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +void print_idecode_issue_function_header + (lf *file, + const char *processor, + function_decl_type decl_type, int nr_prefetched_words); + +void print_idecode_globals (lf *file); + +void print_idecode_lookups + (lf *file, gen_entry *table, cache_entry *cache_rules); + +void print_idecode_body (lf *file, gen_entry *table, const char *result); + + + +/* Output code to do any final checks on the decoded instruction. + This includes things like verifying any on decoded fields have the + correct value and checking that (for floating point) floating point + hardware isn't disabled */ + +extern void print_idecode_validate + (lf *file, insn_entry * instruction, insn_opcodes *opcode_paths);
gen-idecode.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen.c =================================================================== --- gen.c (nonexistent) +++ gen.c (revision 841) @@ -0,0 +1,1764 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +#include "misc.h" +#include "lf.h" +#include "table.h" +#include "filter.h" + +#include "igen.h" +#include "ld-insn.h" +#include "ld-decode.h" +#include "gen.h" + +static insn_uint +sub_val (insn_uint val, int val_last_pos, int first_pos, int last_pos) +{ + return ((val >> (val_last_pos - last_pos)) + & (((insn_uint) 1 << (last_pos - first_pos + 1)) - 1)); +} + +static void +update_depth (lf *file, gen_entry *entry, int depth, void *data) +{ + int *max_depth = (int *) data; + if (*max_depth < depth) + *max_depth = depth; +} + + +int +gen_entry_depth (gen_entry *table) +{ + int depth = 0; + gen_entry_traverse_tree (NULL, table, 1, NULL, /*start */ + update_depth, NULL, /*end */ + &depth); /* data */ + return depth; +} + + +static void +print_gen_entry_path (line_ref *line, gen_entry *table, error_func *print) +{ + if (table->parent == NULL) + { + if (table->top->model != NULL) + print (line, "%s", table->top->model->name); + else + print (line, ""); + } + else + { + print_gen_entry_path (line, table->parent, print); + print (NULL, ".%d", table->opcode_nr); + } +} + +static void +print_gen_entry_insns (gen_entry *table, + error_func *print, + char *first_message, char *next_message) +{ + insn_list *i; + char *message; + message = first_message; + for (i = table->insns; i != NULL; i = i->next) + { + insn_entry *insn = i->insn; + print_gen_entry_path (insn->line, table, print); + print (NULL, ": %s.%s %s\n", insn->format_name, insn->name, message); + if (next_message != NULL) + message = next_message; + } +} + +/* same as strcmp */ +static int +insn_field_cmp (insn_word_entry *l, insn_word_entry *r) +{ + while (1) + { + int bit_nr; + if (l == NULL && r == NULL) + return 0; /* all previous fields the same */ + if (l == NULL) + return -1; /* left shorter than right */ + if (r == NULL) + return +1; /* left longer than right */ + for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++) + { + if (l->bit[bit_nr]->field->type != insn_field_string) + continue; + if (r->bit[bit_nr]->field->type != insn_field_string) + continue; + if (l->bit[bit_nr]->field->conditions == NULL) + continue; + if (r->bit[bit_nr]->field->conditions == NULL) + continue; + if (0) + printf ("%s%s%s VS %s%s%s\n", + l->bit[bit_nr]->field->val_string, + l->bit[bit_nr]->field->conditions->test == + insn_field_cond_eq ? "=" : "!", + l->bit[bit_nr]->field->conditions->string, + r->bit[bit_nr]->field->val_string, + r->bit[bit_nr]->field->conditions->test == + insn_field_cond_eq ? "=" : "!", + r->bit[bit_nr]->field->conditions->string); + if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq + && r->bit[bit_nr]->field->conditions->test == + insn_field_cond_eq) + { + if (l->bit[bit_nr]->field->conditions->type == + insn_field_cond_field + && r->bit[bit_nr]->field->conditions->type == + insn_field_cond_field) + /* somewhat arbitrary */ + { + int cmp = strcmp (l->bit[bit_nr]->field->conditions->string, + r->bit[bit_nr]->field->conditions-> + string); + if (cmp != 0) + return cmp; + else + continue; + } + if (l->bit[bit_nr]->field->conditions->type == + insn_field_cond_field) + return +1; + if (r->bit[bit_nr]->field->conditions->type == + insn_field_cond_field) + return -1; + /* The case of both fields having constant values should have + already have been handled because such fields are converted + into normal constant fields. */ + continue; + } + if (l->bit[bit_nr]->field->conditions->test == insn_field_cond_eq) + return +1; /* left = only */ + if (r->bit[bit_nr]->field->conditions->test == insn_field_cond_eq) + return -1; /* right = only */ + /* FIXME: Need to some what arbitrarily order conditional lists */ + continue; + } + l = l->next; + r = r->next; + } +} + +/* same as strcmp */ +static int +insn_word_cmp (insn_word_entry *l, insn_word_entry *r) +{ + while (1) + { + int bit_nr; + if (l == NULL && r == NULL) + return 0; /* all previous fields the same */ + if (l == NULL) + return -1; /* left shorter than right */ + if (r == NULL) + return +1; /* left longer than right */ + for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++) + { + if (l->bit[bit_nr]->mask < r->bit[bit_nr]->mask) + return -1; + if (l->bit[bit_nr]->mask > r->bit[bit_nr]->mask) + return 1; + if (l->bit[bit_nr]->value < r->bit[bit_nr]->value) + return -1; + if (l->bit[bit_nr]->value > r->bit[bit_nr]->value) + return 1; + } + l = l->next; + r = r->next; + } +} + +/* same as strcmp */ +static int +opcode_bit_cmp (opcode_bits *l, opcode_bits *r) +{ + if (l == NULL && r == NULL) + return 0; /* all previous bits the same */ + if (l == NULL) + return -1; /* left shorter than right */ + if (r == NULL) + return +1; /* left longer than right */ + /* most significant word */ + if (l->field->word_nr < r->field->word_nr) + return +1; /* left has more significant word */ + if (l->field->word_nr > r->field->word_nr) + return -1; /* right has more significant word */ + /* most significant bit? */ + if (l->first < r->first) + return +1; /* left as more significant bit */ + if (l->first > r->first) + return -1; /* right as more significant bit */ + /* nr bits? */ + if (l->last < r->last) + return +1; /* left as less bits */ + if (l->last > r->last) + return -1; /* right as less bits */ + /* value? */ + if (l->value < r->value) + return -1; + if (l->value > r->value) + return 1; + return 0; +} + + +/* same as strcmp */ +static int +opcode_bits_cmp (opcode_bits *l, opcode_bits *r) +{ + while (1) + { + int cmp; + if (l == NULL && r == NULL) + return 0; /* all previous bits the same */ + cmp = opcode_bit_cmp (l, r); + if (cmp != 0) + return cmp; + l = l->next; + r = r->next; + } +} + +/* same as strcmp */ +static opcode_bits * +new_opcode_bits (opcode_bits *old_bits, + int value, + int first, + int last, insn_field_entry *field, opcode_field *opcode) +{ + opcode_bits *new_bits = ZALLOC (opcode_bits); + new_bits->field = field; + new_bits->value = value; + new_bits->first = first; + new_bits->last = last; + new_bits->opcode = opcode; + + if (old_bits != NULL) + { + opcode_bits *new_list; + opcode_bits **last = &new_list; + new_list = new_opcode_bits (old_bits->next, + old_bits->value, + old_bits->first, + old_bits->last, + old_bits->field, old_bits->opcode); + while (*last != NULL) + { + int cmp = opcode_bit_cmp (new_bits, *last); + if (cmp < 0) /* new < new_list */ + { + break; + } + if (cmp == 0) + { + ERROR ("Duplicated insn bits in list"); + } + last = &(*last)->next; + } + new_bits->next = *last; + *last = new_bits; + return new_list; + } + else + { + return new_bits; + } +} + +/* Same as strcmp(). */ +static int +name_cmp (const char *l, const char *r) +{ + if (l == NULL && r == NULL) + return 0; + if (l != NULL && r == NULL) + return -1; + if (l == NULL && r != NULL) + return +1; + return strcmp (l, r); +} + + +typedef enum +{ + merge_duplicate_insns, + report_duplicate_insns, +} +duplicate_insn_actions; + +static insn_list * +insn_list_insert (insn_list **cur_insn_ptr, + int *nr_insns, + insn_entry * insn, + opcode_bits *expanded_bits, + opcode_field *opcodes, + int nr_prefetched_words, + duplicate_insn_actions duplicate_action) +{ + /* insert it according to the order of the fields & bits */ + for (; (*cur_insn_ptr) != NULL; cur_insn_ptr = &(*cur_insn_ptr)->next) + { + int cmp; + + /* key#1 sort according to the constant fields of each instruction */ + cmp = insn_word_cmp (insn->words, (*cur_insn_ptr)->insn->words); + if (cmp < 0) + break; + else if (cmp > 0) + continue; + + /* key#2 sort according to the expanded bits of each instruction */ + cmp = opcode_bits_cmp (expanded_bits, (*cur_insn_ptr)->expanded_bits); + if (cmp < 0) + break; + else if (cmp > 0) + continue; + + /* key#3 sort according to the non-constant fields of each instruction */ + cmp = insn_field_cmp (insn->words, (*cur_insn_ptr)->insn->words); + if (cmp < 0) + break; + else if (cmp > 0) + continue; + + if (duplicate_action == merge_duplicate_insns) + { + /* key#4: If we're going to merge duplicates, also sort + according to the format_name. Two instructions with + identical decode patterns, but different names, are + considered different when merging. Duplicates are only + important when creating a decode table (implied by + report_duplicate_insns) as such a table only has the + instruction's bit code as a way of differentiating + between instructions. */ + int cmp = name_cmp (insn->format_name, + (*cur_insn_ptr)->insn->format_name); + if (cmp < 0) + break; + else if (cmp > 0) + continue; + } + + if (duplicate_action == merge_duplicate_insns) + { + /* key#5: If we're going to merge duplicates, also sort + according to the name. See comment above for + format_name. */ + int cmp = name_cmp (insn->name, (*cur_insn_ptr)->insn->name); + if (cmp < 0) + break; + else if (cmp > 0) + continue; + } + + /* duplicate keys, report problem */ + switch (duplicate_action) + { + case report_duplicate_insns: + /* It would appear that we have two instructions with the + same constant field values across all words and bits. + This error can also occure when insn_field_cmp() is + failing to differentiate between two instructions that + differ only in their conditional fields. */ + warning (insn->line, + "Two instructions with identical constant fields\n"); + error ((*cur_insn_ptr)->insn->line, + "Location of duplicate instruction\n"); + case merge_duplicate_insns: + /* Add the opcode path to the instructions list */ + if (options.trace.insn_insertion) + { + notify ((*cur_insn_ptr)->insn->line, + "%s.%s: insert merge %s.%s\n", + (*cur_insn_ptr)->insn->format_name, + (*cur_insn_ptr)->insn->name, + insn->format_name, + insn->name); + } + if (opcodes != NULL) + { + insn_opcodes **last = &(*cur_insn_ptr)->opcodes; + while (*last != NULL) + { + last = &(*last)->next; + } + (*last) = ZALLOC (insn_opcodes); + (*last)->opcode = opcodes; + } + /* Use the larger nr_prefetched_words */ + if ((*cur_insn_ptr)->nr_prefetched_words < nr_prefetched_words) + (*cur_insn_ptr)->nr_prefetched_words = nr_prefetched_words; + return (*cur_insn_ptr); + } + + } + + /* create a new list entry and insert it */ + { + insn_list *new_insn = ZALLOC (insn_list); + if (options.trace.insn_insertion) + { + notify (insn->line, + "%s.%s: insert new\n", + insn->format_name, + insn->name); + } + new_insn->insn = insn; + new_insn->expanded_bits = expanded_bits; + new_insn->next = (*cur_insn_ptr); + new_insn->nr_prefetched_words = nr_prefetched_words; + if (opcodes != NULL) + { + new_insn->opcodes = ZALLOC (insn_opcodes); + new_insn->opcodes->opcode = opcodes; + } + (*cur_insn_ptr) = new_insn; + } + + *nr_insns += 1; + + return (*cur_insn_ptr); +} + + +extern void +gen_entry_traverse_tree (lf *file, + gen_entry *table, + int depth, + gen_entry_handler * start, + gen_entry_handler * leaf, + gen_entry_handler * end, void *data) +{ + gen_entry *entry; + + ASSERT (table !=NULL); + ASSERT (table->opcode != NULL); + ASSERT (table->nr_entries > 0); + ASSERT (table->entries != 0); + + /* prefix */ + if (start != NULL && depth >= 0) + { + start (file, table, depth, data); + } + /* infix leaves */ + for (entry = table->entries; entry != NULL; entry = entry->sibling) + { + if (entry->entries != NULL && depth != 0) + { + gen_entry_traverse_tree (file, entry, depth + 1, + start, leaf, end, data); + } + else if (depth >= 0) + { + if (leaf != NULL) + { + leaf (file, entry, depth, data); + } + } + } + /* postfix */ + if (end != NULL && depth >= 0) + { + end (file, table, depth, data); + } +} + + + +/* create a list element containing a single gen_table entry */ + +static gen_list * +make_table (insn_table *isa, decode_table *rules, model_entry *model) +{ + insn_entry *insn; + gen_list *entry = ZALLOC (gen_list); + entry->table = ZALLOC (gen_entry); + entry->table->top = entry; + entry->model = model; + entry->isa = isa; + for (insn = isa->insns; insn != NULL; insn = insn->next) + { + if (model == NULL + || insn->processors == NULL + || filter_is_member (insn->processors, model->name)) + { + insn_list_insert (&entry->table->insns, &entry->table->nr_insns, insn, NULL, /* expanded_bits - none yet */ + NULL, /* opcodes - none yet */ + 0, /* nr_prefetched_words - none yet */ + report_duplicate_insns); + } + } + entry->table->opcode_rule = rules; + return entry; +} + + +gen_table * +make_gen_tables (insn_table *isa, decode_table *rules) +{ + gen_table *gen = ZALLOC (gen_table); + gen->isa = isa; + gen->rules = rules; + if (options.gen.multi_sim) + { + gen_list **last = &gen->tables; + model_entry *model; + filter *processors; + if (options.model_filter != NULL) + processors = options.model_filter; + else + processors = isa->model->processors; + for (model = isa->model->models; model != NULL; model = model->next) + { + if (filter_is_member (processors, model->name)) + { + *last = make_table (isa, rules, model); + last = &(*last)->next; + } + } + } + else + { + gen->tables = make_table (isa, rules, NULL); + } + return gen; +} + + +/****************************************************************/ + +#if 0 +typedef enum +{ + field_is_not_constant = 0, + field_constant_int = 1, + field_constant_reserved = 2, + field_constant_string = 3 +} +constant_field_types; + +static constant_field_types +insn_field_is_constant (insn_field * field, decode_table *rule) +{ + switch (field->type) + { + case insn_field_int: + /* field is an integer */ + return field_constant_int; + case insn_field_reserved: + /* field is `/' and treating that as a constant */ + if (rule->with_zero_reserved) + return field_constant_reserved; + else + return field_is_not_constant; + case insn_field_wild: + return field_is_not_constant; /* never constant */ + case insn_field_string: + /* field, though variable, is on the list of forced constants */ + if (filter_is_member (rule->constant_field_names, field->val_string)) + return field_constant_string; + else + return field_is_not_constant; + } + ERROR ("Internal error"); + return field_is_not_constant; +} +#endif + + +/****************************************************************/ + + +/* Is the bit, according to the decode rule, identical across all the + instructions? */ +static int +insns_bit_useless (insn_list *insns, decode_table *rule, int bit_nr) +{ + insn_list *entry; + int value = -1; + int is_useless = 1; /* cleared if something actually found */ + + /* check the instructions for some constant value in at least one of + the bit fields */ + for (entry = insns; entry != NULL; entry = entry->next) + { + insn_word_entry *word = entry->insn->word[rule->word_nr]; + insn_bit_entry *bit = word->bit[bit_nr]; + switch (bit->field->type) + { + case insn_field_invalid: + ASSERT (0); + break; + case insn_field_wild: + case insn_field_reserved: + /* neither useless or useful - ignore */ + break; + case insn_field_int: + switch (rule->search) + { + case decode_find_strings: + /* an integer isn't a string */ + return 1; + case decode_find_constants: + case decode_find_mixed: + /* an integer is useful if its value isn't the same + between all instructions. The first time through the + value is saved, the second time through (if the + values differ) it is marked as useful. */ + if (value < 0) + value = bit->value; + else if (value != bit->value) + is_useless = 0; + break; + } + break; + case insn_field_string: + switch (rule->search) + { + case decode_find_strings: + /* at least one string, keep checking */ + is_useless = 0; + break; + case decode_find_constants: + case decode_find_mixed: + if (filter_is_member (rule->constant_field_names, + bit->field->val_string)) + /* a string field forced to constant? */ + is_useless = 0; + else if (rule->search == decode_find_constants) + /* the string field isn't constant */ + return 1; + break; + } + } + } + + /* Given only one constant value has been found, check through all + the instructions to see if at least one conditional makes it + usefull */ + if (value >= 0 && is_useless) + { + for (entry = insns; entry != NULL; entry = entry->next) + { + insn_word_entry *word = entry->insn->word[rule->word_nr]; + insn_bit_entry *bit = word->bit[bit_nr]; + switch (bit->field->type) + { + case insn_field_invalid: + ASSERT (0); + break; + case insn_field_wild: + case insn_field_reserved: + case insn_field_int: + /* already processed */ + break; + case insn_field_string: + switch (rule->search) + { + case decode_find_strings: + case decode_find_constants: + /* already processed */ + break; + case decode_find_mixed: + /* string field with conditions. If this condition + eliminates the value then the compare is useful */ + if (bit->field->conditions != NULL) + { + insn_field_cond *condition; + int shift = bit->field->last - bit_nr; + for (condition = bit->field->conditions; + condition != NULL; condition = condition->next) + { + switch (condition->type) + { + case insn_field_cond_value: + switch (condition->test) + { + case insn_field_cond_ne: + if (((condition->value >> shift) & 1) + == (unsigned) value) + /* conditional field excludes the + current value */ + is_useless = 0; + break; + case insn_field_cond_eq: + if (((condition->value >> shift) & 1) + != (unsigned) value) + /* conditional field requires the + current value */ + is_useless = 0; + break; + } + break; + case insn_field_cond_field: + /* are these handled separatly? */ + break; + } + } + } + } + } + } + } + + return is_useless; +} + + +/* go through a gen-table's list of instruction formats looking for a + range of bits that meet the decode table RULEs requirements */ + +static opcode_field * +gen_entry_find_opcode_field (insn_list *insns, + decode_table *rule, int string_only) +{ + opcode_field curr_opcode; + ASSERT (rule != NULL); + + memset (&curr_opcode, 0, sizeof (curr_opcode)); + curr_opcode.word_nr = rule->word_nr; + curr_opcode.first = rule->first; + curr_opcode.last = rule->last; + + /* Try to reduce the size of first..last in accordance with the + decode rules */ + + while (curr_opcode.first <= rule->last) + { + if (insns_bit_useless (insns, rule, curr_opcode.first)) + curr_opcode.first++; + else + break; + } + while (curr_opcode.last >= rule->first) + { + if (insns_bit_useless (insns, rule, curr_opcode.last)) + curr_opcode.last--; + else + break; + } + + +#if 0 + for (entry = insns; entry != NULL; entry = entry->next) + { + insn_word_entry *fields = entry->insn->word[rule->word_nr]; + opcode_field new_opcode; + + ASSERT (fields != NULL); + + /* find a start point for the opcode field */ + new_opcode.first = rule->first; + while (new_opcode.first <= rule->last + && (!string_only + || + (insn_field_is_constant (fields->bit[new_opcode.first], rule) + != field_constant_string)) && (string_only + || + (insn_field_is_constant + (fields-> + bit[new_opcode.first], + rule) == + field_is_not_constant))) + { + int new_first = fields->bit[new_opcode.first]->last + 1; + ASSERT (new_first > new_opcode.first); + new_opcode.first = new_first; + } + ASSERT (new_opcode.first > rule->last + || (string_only + && insn_field_is_constant (fields->bit[new_opcode.first], + rule) == field_constant_string) + || (!string_only + && insn_field_is_constant (fields->bit[new_opcode.first], + rule))); + + /* find the end point for the opcode field */ + new_opcode.last = rule->last; + while (new_opcode.last >= rule->first + && (!string_only + || insn_field_is_constant (fields->bit[new_opcode.last], + rule) != field_constant_string) + && (string_only + || !insn_field_is_constant (fields->bit[new_opcode.last], + rule))) + { + int new_last = fields->bit[new_opcode.last]->first - 1; + ASSERT (new_last < new_opcode.last); + new_opcode.last = new_last; + } + ASSERT (new_opcode.last < rule->first + || (string_only + && insn_field_is_constant (fields->bit[new_opcode.last], + rule) == field_constant_string) + || (!string_only + && insn_field_is_constant (fields->bit[new_opcode.last], + rule))); + + /* now see if our current opcode needs expanding to include the + interesting fields within this instruction */ + if (new_opcode.first <= rule->last + && curr_opcode.first > new_opcode.first) + curr_opcode.first = new_opcode.first; + if (new_opcode.last >= rule->first + && curr_opcode.last < new_opcode.last) + curr_opcode.last = new_opcode.last; + + } +#endif + + /* did the final opcode field end up being empty? */ + if (curr_opcode.first > curr_opcode.last) + { + return NULL; + } + ASSERT (curr_opcode.last >= rule->first); + ASSERT (curr_opcode.first <= rule->last); + ASSERT (curr_opcode.first <= curr_opcode.last); + + /* Ensure that, for the non string only case, the opcode includes + the range forced_first .. forced_last */ + if (!string_only && curr_opcode.first > rule->force_first) + { + curr_opcode.first = rule->force_first; + } + if (!string_only && curr_opcode.last < rule->force_last) + { + curr_opcode.last = rule->force_last; + } + + /* For the string only case, force just the lower bound (so that the + shift can be eliminated) */ + if (string_only && rule->force_last == options.insn_bit_size - 1) + { + curr_opcode.last = options.insn_bit_size - 1; + } + + /* handle any special cases */ + switch (rule->type) + { + case normal_decode_rule: + /* let the above apply */ + curr_opcode.nr_opcodes = + (1 << (curr_opcode.last - curr_opcode.first + 1)); + break; + case boolean_rule: + curr_opcode.is_boolean = 1; + curr_opcode.boolean_constant = rule->constant; + curr_opcode.nr_opcodes = 2; + break; + } + + { + opcode_field *new_field = ZALLOC (opcode_field); + memcpy (new_field, &curr_opcode, sizeof (opcode_field)); + return new_field; + } +} + + +static void +gen_entry_insert_insn (gen_entry *table, + insn_entry * old_insn, + int new_word_nr, + int new_nr_prefetched_words, + int new_opcode_nr, opcode_bits *new_bits) +{ + gen_entry **entry = &table->entries; + + /* find the new table for this entry */ + while ((*entry) != NULL && (*entry)->opcode_nr < new_opcode_nr) + { + entry = &(*entry)->sibling; + } + + if ((*entry) == NULL || (*entry)->opcode_nr != new_opcode_nr) + { + /* insert the missing entry */ + gen_entry *new_entry = ZALLOC (gen_entry); + new_entry->sibling = (*entry); + (*entry) = new_entry; + table->nr_entries++; + /* fill it in */ + new_entry->top = table->top; + new_entry->opcode_nr = new_opcode_nr; + new_entry->word_nr = new_word_nr; + new_entry->expanded_bits = new_bits; + new_entry->opcode_rule = table->opcode_rule->next; + new_entry->parent = table; + new_entry->nr_prefetched_words = new_nr_prefetched_words; + } + /* ASSERT new_bits == cur_entry bits */ + ASSERT ((*entry) != NULL && (*entry)->opcode_nr == new_opcode_nr); + insn_list_insert (&(*entry)->insns, &(*entry)->nr_insns, old_insn, NULL, /* expanded_bits - only in final list */ + NULL, /* opcodes - only in final list */ + new_nr_prefetched_words, /* for this table */ + report_duplicate_insns); +} + + +static void +gen_entry_expand_opcode (gen_entry *table, + insn_entry * instruction, + int bit_nr, int opcode_nr, opcode_bits *bits) +{ + if (bit_nr > table->opcode->last) + { + /* Only include the hardwired bit information with an entry IF + that entry (and hence its functions) are being duplicated. */ + if (options.trace.insn_expansion) + { + print_gen_entry_path (table->opcode_rule->line, table, notify); + notify (NULL, ": insert %d - %s.%s%s\n", + opcode_nr, + instruction->format_name, + instruction->name, + (table->opcode_rule-> + with_duplicates ? " (duplicated)" : "")); + } + if (table->opcode_rule->with_duplicates) + { + gen_entry_insert_insn (table, instruction, + table->opcode->word_nr, + table->nr_prefetched_words, opcode_nr, bits); + } + else + { + gen_entry_insert_insn (table, instruction, + table->opcode->word_nr, + table->nr_prefetched_words, opcode_nr, NULL); + } + } + else + { + insn_word_entry *word = instruction->word[table->opcode->word_nr]; + insn_field_entry *field = word->bit[bit_nr]->field; + int last_pos = ((field->last < table->opcode->last) + ? field->last : table->opcode->last); + int first_pos = ((field->first > table->opcode->first) + ? field->first : table->opcode->first); + int width = last_pos - first_pos + 1; + switch (field->type) + { + case insn_field_int: + { + int val; + val = sub_val (field->val_int, field->last, first_pos, last_pos); + gen_entry_expand_opcode (table, instruction, + last_pos + 1, + ((opcode_nr << width) | val), bits); + break; + } + default: + { + if (field->type == insn_field_reserved) + gen_entry_expand_opcode (table, instruction, + last_pos + 1, + ((opcode_nr << width)), bits); + else + { + int val; + int last_val = (table->opcode->is_boolean ? 2 : (1 << width)); + for (val = 0; val < last_val; val++) + { + /* check to see if the value has been precluded + (by a conditional) in some way */ + int is_precluded; + insn_field_cond *condition; + for (condition = field->conditions, is_precluded = 0; + condition != NULL && !is_precluded; + condition = condition->next) + { + switch (condition->type) + { + case insn_field_cond_value: + { + int value = + sub_val (condition->value, field->last, + first_pos, last_pos); + switch (condition->test) + { + case insn_field_cond_ne: + if (value == val) + is_precluded = 1; + break; + case insn_field_cond_eq: + if (value != val) + is_precluded = 1; + break; + } + break; + } + case insn_field_cond_field: + { + int value = -1; + opcode_bits *bit; + gen_entry *t = NULL; + /* Try to find a value for the + conditional by looking back through + the previously defined bits for one + that covers the designated + conditional field */ + for (bit = bits; bit != NULL; bit = bit->next) + { + if (bit->field->word_nr == + condition->field->word_nr + && bit->first <= condition->field->first + && bit->last >= condition->field->last) + { + /* the bit field fully specified + the conditional field's value */ + value = sub_val (bit->value, bit->last, + condition->field-> + first, + condition->field-> + last); + } + } + /* Try to find a value by looking + through this and previous tables */ + if (bit == NULL) + { + for (t = table; + t->parent != NULL; t = t->parent) + { + if (t->parent->opcode->word_nr == + condition->field->word_nr + && t->parent->opcode->first <= + condition->field->first + && t->parent->opcode->last >= + condition->field->last) + { + /* the table entry fully + specified the condition + field's value */ + /* extract the field's value + from the opcode */ + value = + sub_val (t->opcode_nr, + t->parent->opcode->last, + condition->field->first, + condition->field->last); + /* this is a requirement of + a conditonal field + refering to another field */ + ASSERT ((condition->field->first - + condition->field->last) == + (first_pos - last_pos)); + printf + ("value=%d, opcode_nr=%d, last=%d, [%d..%d]\n", + value, t->opcode_nr, + t->parent->opcode->last, + condition->field->first, + condition->field->last); + } + } + } + if (bit == NULL && t == NULL) + error (instruction->line, + "Conditional `%s' of field `%s' isn't expanded", + condition->string, field->val_string); + switch (condition->test) + { + case insn_field_cond_ne: + if (value == val) + is_precluded = 1; + break; + case insn_field_cond_eq: + if (value != val) + is_precluded = 1; + break; + } + break; + } + } + } + if (!is_precluded) + { + /* Only add additional hardwired bit + information if the entry is not going to + later be combined */ + if (table->opcode_rule->with_combine) + { + gen_entry_expand_opcode (table, instruction, + last_pos + 1, + ((opcode_nr << width) | + val), bits); + } + else + { + opcode_bits *new_bits = + new_opcode_bits (bits, val, + first_pos, last_pos, + field, + table->opcode); + gen_entry_expand_opcode (table, instruction, + last_pos + 1, + ((opcode_nr << width) | + val), new_bits); + } + } + } + } + } + } + } +} + +static void +gen_entry_insert_expanding (gen_entry *table, insn_entry * instruction) +{ + gen_entry_expand_opcode (table, + instruction, + table->opcode->first, 0, table->expanded_bits); +} + + +static int +insns_match_format_names (insn_list *insns, filter *format_names) +{ + if (format_names != NULL) + { + insn_list *i; + for (i = insns; i != NULL; i = i->next) + { + if (i->insn->format_name != NULL + && !filter_is_member (format_names, i->insn->format_name)) + return 0; + } + } + return 1; +} + +static int +table_matches_path (gen_entry *table, decode_path_list *paths) +{ + if (paths == NULL) + return 1; + while (paths != NULL) + { + gen_entry *entry = table; + decode_path *path = paths->path; + while (1) + { + if (entry == NULL && path == NULL) + return 1; + if (entry == NULL || path == NULL) + break; + if (entry->opcode_nr != path->opcode_nr) + break; + entry = entry->parent; + path = path->parent; + } + paths = paths->next; + } + return 0; +} + + +static int +insns_match_conditions (insn_list *insns, decode_cond *conditions) +{ + if (conditions != NULL) + { + insn_list *i; + for (i = insns; i != NULL; i = i->next) + { + decode_cond *cond; + for (cond = conditions; cond != NULL; cond = cond->next) + { + int bit_nr; + if (i->insn->nr_words <= cond->word_nr) + return 0; + for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++) + { + if (!cond->mask[bit_nr]) + continue; + if (!i->insn->word[cond->word_nr]->bit[bit_nr]->mask) + return 0; + if ((i->insn->word[cond->word_nr]->bit[bit_nr]->value + == cond->value[bit_nr]) == !cond->is_equal) + return 0; + } + } + } + } + return 1; +} + +static int +insns_match_nr_words (insn_list *insns, int nr_words) +{ + insn_list *i; + for (i = insns; i != NULL; i = i->next) + { + if (i->insn->nr_words < nr_words) + return 0; + } + return 1; +} + +static int +insn_list_cmp (insn_list *l, insn_list *r) +{ + while (1) + { + insn_entry *insn; + if (l == NULL && r == NULL) + return 0; + if (l == NULL) + return -1; + if (r == NULL) + return 1; + if (l->insn != r->insn) + return -1; /* somewhat arbitrary at present */ + /* skip this insn */ + insn = l->insn; + while (l != NULL && l->insn == insn) + l = l->next; + while (r != NULL && r->insn == insn) + r = r->next; + } +} + + + +static void +gen_entry_expand_insns (gen_entry *table) +{ + decode_table *opcode_rule; + + ASSERT (table->nr_insns >= 1); + + /* determine a valid opcode */ + for (opcode_rule = table->opcode_rule; + opcode_rule != NULL; opcode_rule = opcode_rule->next) + { + char *discard_reason; + if (table->top->model != NULL + && opcode_rule->model_names != NULL + && !filter_is_member (opcode_rule->model_names, + table->top->model->name)) + { + /* the rule isn't applicable to this processor */ + discard_reason = "wrong model"; + } + else if (table->nr_insns == 1 && opcode_rule->conditions == NULL) + { + /* for safety, require a pre-codition when attempting to + apply a rule to a single instruction */ + discard_reason = "need pre-condition when nr-insn == 1"; + } + else if (table->nr_insns == 1 && !opcode_rule->with_duplicates) + { + /* Little point in expanding a single instruction when we're + not duplicating the semantic functions that this table + calls */ + discard_reason = "need duplication with nr-insns == 1"; + } + else + if (!insns_match_format_names + (table->insns, opcode_rule->format_names)) + { + discard_reason = "wrong format name"; + } + else if (!insns_match_nr_words (table->insns, opcode_rule->word_nr + 1)) + { + discard_reason = "wrong nr words"; + } + else if (!table_matches_path (table, opcode_rule->paths)) + { + discard_reason = "path failed"; + } + else + if (!insns_match_conditions (table->insns, opcode_rule->conditions)) + { + discard_reason = "condition failed"; + } + else + { + discard_reason = "no opcode field"; + table->opcode = gen_entry_find_opcode_field (table->insns, + opcode_rule, + table->nr_insns == 1 /*string-only */ + ); + if (table->opcode != NULL) + { + table->opcode_rule = opcode_rule; + break; + } + } + + if (options.trace.rule_rejection) + { + print_gen_entry_path (opcode_rule->line, table, notify); + notify (NULL, ": rule discarded - %s\n", discard_reason); + } + } + + /* did we find anything */ + if (opcode_rule == NULL) + { + /* the decode table failed, this set of instructions haven't + been uniquely identified */ + if (table->nr_insns > 1) + { + print_gen_entry_insns (table, warning, + "was not uniquely decoded", + "decodes to the same entry"); + error (NULL, ""); + } + return; + } + + /* Determine the number of words that must have been prefetched for + this table to function */ + if (table->parent == NULL) + table->nr_prefetched_words = table->opcode_rule->word_nr + 1; + else if (table->opcode_rule->word_nr + 1 > + table->parent->nr_prefetched_words) + table->nr_prefetched_words = table->opcode_rule->word_nr + 1; + else + table->nr_prefetched_words = table->parent->nr_prefetched_words; + + /* back link what we found to its parent */ + if (table->parent != NULL) + { + ASSERT (table->parent->opcode != NULL); + table->opcode->parent = table->parent->opcode; + } + + /* report the rule being used to expand the instructions */ + if (options.trace.rule_selection) + { + print_gen_entry_path (table->opcode_rule->line, table, notify); + notify (NULL, + ": decode - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d\n", + table->opcode->word_nr, + i2target (options.hi_bit_nr, table->opcode->first), + i2target (options.hi_bit_nr, table->opcode->last), + i2target (options.hi_bit_nr, table->opcode_rule->first), + i2target (options.hi_bit_nr, table->opcode_rule->last), + table->opcode->nr_opcodes, table->nr_entries); + } + + /* expand the raw instructions according to the opcode */ + { + insn_list *entry; + for (entry = table->insns; entry != NULL; entry = entry->next) + { + if (options.trace.insn_expansion) + { + print_gen_entry_path (table->opcode_rule->line, table, notify); + notify (NULL, ": expand - %s.%s\n", + entry->insn->format_name, entry->insn->name); + } + gen_entry_insert_expanding (table, entry->insn); + } + } + + /* dump the results */ + if (options.trace.entries) + { + gen_entry *entry; + for (entry = table->entries; entry != NULL; entry = entry->sibling) + { + insn_list *l; + print_gen_entry_path (table->opcode_rule->line, entry, notify); + notify (NULL, ": %d - entries %d -", + entry->opcode_nr, entry->nr_insns); + for (l = entry->insns; l != NULL; l = l->next) + notify (NULL, " %s.%s", l->insn->format_name, l->insn->name); + notify (NULL, "\n"); + } + } + + /* perform a combine pass if needed */ + if (table->opcode_rule->with_combine) + { + gen_entry *entry; + for (entry = table->entries; entry != NULL; entry = entry->sibling) + { + if (entry->combined_parent == NULL) + { + gen_entry **last = &entry->combined_next; + gen_entry *alt; + for (alt = entry->sibling; alt != NULL; alt = alt->sibling) + { + if (alt->combined_parent == NULL + && insn_list_cmp (entry->insns, alt->insns) == 0) + { + alt->combined_parent = entry; + *last = alt; + last = &alt->combined_next; + } + } + } + } + if (options.trace.combine) + { + int nr_unique = 0; + gen_entry *entry; + for (entry = table->entries; entry != NULL; entry = entry->sibling) + { + if (entry->combined_parent == NULL) + { + insn_list *l; + gen_entry *duplicate; + nr_unique++; + print_gen_entry_path (table->opcode_rule->line, entry, + notify); + for (duplicate = entry->combined_next; duplicate != NULL; + duplicate = duplicate->combined_next) + { + notify (NULL, "+%d", duplicate->opcode_nr); + } + notify (NULL, ": entries %d -", entry->nr_insns); + for (l = entry->insns; l != NULL; l = l->next) + { + notify (NULL, " %s.%s", + l->insn->format_name, l->insn->name); + } + notify (NULL, "\n"); + } + } + print_gen_entry_path (table->opcode_rule->line, table, notify); + notify (NULL, + ": combine - word %d, bits [%d..%d] in [%d..%d], opcodes %d, entries %d, unique %d\n", + table->opcode->word_nr, i2target (options.hi_bit_nr, + table->opcode->first), + i2target (options.hi_bit_nr, table->opcode->last), + i2target (options.hi_bit_nr, table->opcode_rule->first), + i2target (options.hi_bit_nr, table->opcode_rule->last), + table->opcode->nr_opcodes, table->nr_entries, nr_unique); + } + } + + /* Check that the rule did more than re-arange the order of the + instructions */ + { + gen_entry *entry; + for (entry = table->entries; entry != NULL; entry = entry->sibling) + { + if (entry->combined_parent == NULL) + { + if (insn_list_cmp (table->insns, entry->insns) == 0) + { + print_gen_entry_path (table->opcode_rule->line, table, + warning); + warning (NULL, + ": Applying rule just copied all instructions\n"); + print_gen_entry_insns (entry, warning, "Copied", NULL); + error (NULL, ""); + } + } + } + } + + /* if some form of expanded table, fill in the missing dots */ + switch (table->opcode_rule->gen) + { + case padded_switch_gen: + case array_gen: + case goto_switch_gen: + if (!table->opcode->is_boolean) + { + gen_entry **entry = &table->entries; + gen_entry *illegals = NULL; + gen_entry **last_illegal = &illegals; + int opcode_nr = 0; + while (opcode_nr < table->opcode->nr_opcodes) + { + if ((*entry) == NULL || (*entry)->opcode_nr != opcode_nr) + { + /* missing - insert it under our feet at *entry */ + gen_entry_insert_insn (table, table->top->isa->illegal_insn, table->opcode->word_nr, 0, /* nr_prefetched_words == 0 for invalid */ + opcode_nr, NULL); + ASSERT ((*entry) != NULL); + ASSERT ((*entry)->opcode_nr == opcode_nr); + (*last_illegal) = *entry; + (*last_illegal)->combined_parent = illegals; + last_illegal = &(*last_illegal)->combined_next; + } + entry = &(*entry)->sibling; + opcode_nr++; + } + /* oops, will have pointed the first illegal insn back to + its self. Fix this */ + if (illegals != NULL) + illegals->combined_parent = NULL; + } + break; + case switch_gen: + case invalid_gen: + /* ignore */ + break; + } + + /* and do the same for the newly created sub entries but *only* + expand entries that haven't been combined. */ + { + gen_entry *entry; + for (entry = table->entries; entry != NULL; entry = entry->sibling) + { + if (entry->combined_parent == NULL) + { + gen_entry_expand_insns (entry); + } + } + } +} + +void +gen_tables_expand_insns (gen_table *gen) +{ + gen_list *entry; + for (entry = gen->tables; entry != NULL; entry = entry->next) + { + gen_entry_expand_insns (entry->table); + } +} + + +/* create a list of all the semantic functions that need to be + generated. Eliminate any duplicates. Verify that the decode stage + worked. */ + +static void +make_gen_semantics_list (lf *file, gen_entry *entry, int depth, void *data) +{ + gen_table *gen = (gen_table *) data; + insn_list *insn; + /* Not interested in an entrie that have been combined into some + other entry at the same level */ + if (entry->combined_parent != NULL) + return; + + /* a leaf should contain exactly one instruction. If not the decode + stage failed. */ + ASSERT (entry->nr_insns == 1); + + /* Enter this instruction into the list of semantic functions. */ + insn = insn_list_insert (&gen->semantics, &gen->nr_semantics, + entry->insns->insn, + entry->expanded_bits, + entry->parent->opcode, + entry->insns->nr_prefetched_words, + merge_duplicate_insns); + /* point the table entry at the real semantic function */ + ASSERT (insn != NULL); + entry->insns->semantic = insn; +} + + +void +gen_tables_expand_semantics (gen_table *gen) +{ + gen_list *entry; + for (entry = gen->tables; entry != NULL; entry = entry->next) + { + gen_entry_traverse_tree (NULL, entry->table, 1, /* depth */ + NULL, /* start-handler */ + make_gen_semantics_list, /* leaf-handler */ + NULL, /* end-handler */ + gen); /* data */ + } +} + + + +#ifdef MAIN + + +static void +dump_opcode_field (lf *file, + char *prefix, + opcode_field *field, char *suffix, int levels) +{ + lf_printf (file, "%s(opcode_field *) 0x%lx", prefix, (long) field); + if (levels && field != NULL) + { + lf_indent (file, +1); + lf_printf (file, "\n(first %d)", field->first); + lf_printf (file, "\n(last %d)", field->last); + lf_printf (file, "\n(nr_opcodes %d)", field->nr_opcodes); + lf_printf (file, "\n(is_boolean %d)", field->is_boolean); + lf_printf (file, "\n(boolean_constant %d)", field->boolean_constant); + dump_opcode_field (file, "\n(parent ", field->parent, ")", levels - 1); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + + +static void +dump_opcode_bits (lf *file, + char *prefix, opcode_bits *bits, char *suffix, int levels) +{ + lf_printf (file, "%s(opcode_bits *) 0x%lx", prefix, (long) bits); + + if (levels && bits != NULL) + { + lf_indent (file, +1); + lf_printf (file, "\n(value %d)", bits->value); + dump_opcode_field (file, "\n(opcode ", bits->opcode, ")", 0); + dump_insn_field (file, "\n(field ", bits->field, ")"); + dump_opcode_bits (file, "\n(next ", bits->next, ")", levels - 1); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + + + +static void +dump_insn_list (lf *file, char *prefix, insn_list *entry, char *suffix) +{ + lf_printf (file, "%s(insn_list *) 0x%lx", prefix, (long) entry); + + if (entry != NULL) + { + lf_indent (file, +1); + dump_insn_entry (file, "\n(insn ", entry->insn, ")"); + lf_printf (file, "\n(next 0x%lx)", (long) entry->next); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + + +static void +dump_insn_word_entry_list_entries (lf *file, + char *prefix, + insn_list *entry, char *suffix) +{ + lf_printf (file, "%s", prefix); + while (entry != NULL) + { + dump_insn_list (file, "\n(", entry, ")"); + entry = entry->next; + } + lf_printf (file, "%s", suffix); +} + + +static void +dump_gen_entry (lf *file, + char *prefix, gen_entry *table, char *suffix, int levels) +{ + + lf_printf (file, "%s(gen_entry *) 0x%lx", prefix, (long) table); + + if (levels && table !=NULL) + { + + lf_indent (file, +1); + lf_printf (file, "\n(opcode_nr %d)", table->opcode_nr); + lf_printf (file, "\n(word_nr %d)", table->word_nr); + dump_opcode_bits (file, "\n(expanded_bits ", table->expanded_bits, ")", + -1); + lf_printf (file, "\n(nr_insns %d)", table->nr_insns); + dump_insn_word_entry_list_entries (file, "\n(insns ", table->insns, + ")"); + dump_decode_rule (file, "\n(opcode_rule ", table->opcode_rule, ")"); + dump_opcode_field (file, "\n(opcode ", table->opcode, ")", 0); + lf_printf (file, "\n(nr_entries %d)", table->nr_entries); + dump_gen_entry (file, "\n(entries ", table->entries, ")", + table->nr_entries); + dump_gen_entry (file, "\n(sibling ", table->sibling, ")", levels - 1); + dump_gen_entry (file, "\n(parent ", table->parent, ")", 0); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + +static void +dump_gen_list (lf *file, + char *prefix, gen_list *entry, char *suffix, int levels) +{ + while (entry != NULL) + { + lf_printf (file, "%s(gen_list *) 0x%lx", prefix, (long) entry); + dump_gen_entry (file, "\n(", entry->table, ")", levels); + lf_printf (file, "\n(next (gen_list *) 0x%lx)", (long) entry->next); + lf_printf (file, "%s", suffix); + } +} + + +static void +dump_gen_table (lf *file, + char *prefix, gen_table *gen, char *suffix, int levels) +{ + lf_printf (file, "%s(gen_table *) 0x%lx", prefix, (long) gen); + lf_printf (file, "\n(isa (insn_table *) 0x%lx)", (long) gen->isa); + lf_printf (file, "\n(rules (decode_table *) 0x%lx)", (long) gen->rules); + dump_gen_list (file, "\n(", gen->tables, ")", levels); + lf_printf (file, "%s", suffix); +} + + +igen_options options; + +int +main (int argc, char **argv) +{ + decode_table *decode_rules; + insn_table *instructions; + gen_table *gen; + lf *l; + + if (argc != 7) + error (NULL, + "Usage: insn \n"); + + INIT_OPTIONS (options); + + filter_parse (&options.flags_filter, argv[1]); + + options.hi_bit_nr = a2i (argv[2]); + options.insn_bit_size = a2i (argv[3]); + options.insn_specifying_widths = a2i (argv[4]); + ASSERT (options.hi_bit_nr < options.insn_bit_size); + + instructions = load_insn_table (argv[6], NULL); + decode_rules = load_decode_table (argv[5]); + gen = make_gen_tables (instructions, decode_rules); + + gen_tables_expand_insns (gen); + + l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn"); + + dump_gen_table (l, "(", gen, ")\n", -1); + return 0; +} + +#endif
gen.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen.h =================================================================== --- gen.h (nonexistent) +++ gen.h (revision 841) @@ -0,0 +1,212 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +typedef struct _opcode_field opcode_field; +struct _opcode_field +{ + int word_nr; + int first; + int last; + int is_boolean; + int nr_opcodes; + unsigned boolean_constant; + opcode_field *parent; +}; + +typedef struct _opcode_bits opcode_bits; +struct _opcode_bits +{ + int value; + int first; + int last; + insn_field_entry *field; + opcode_field *opcode; + opcode_bits *next; +}; + +typedef struct _insn_opcodes insn_opcodes; +struct _insn_opcodes +{ + opcode_field *opcode; + insn_opcodes *next; +}; + +typedef struct _insn_list insn_list; +struct _insn_list +{ + /* the instruction */ + insn_entry *insn; + /* list of non constant bits that have been made constant */ + opcode_bits *expanded_bits; + /* list of the various opcode field paths used to reach this + instruction */ + insn_opcodes *opcodes; + /* number of prefetched words for this instruction */ + int nr_prefetched_words; + /* The semantic function list_entry corresponding to this insn */ + insn_list *semantic; + /* linked list */ + insn_list *next; +}; + +/* forward */ +typedef struct _gen_list gen_list; + +typedef struct _gen_entry gen_entry; +struct _gen_entry +{ + + /* as an entry in a table */ + int word_nr; + int opcode_nr; + gen_entry *sibling; + opcode_bits *expanded_bits; + gen_entry *parent; /* parent has the opcode* data */ + + /* as a table containing entries */ + decode_table *opcode_rule; + opcode_field *opcode; + int nr_prefetched_words; + int nr_entries; + gen_entry *entries; + + /* as both an entry and a table */ + int nr_insns; + insn_list *insns; + + /* if siblings are being combined */ + gen_entry *combined_next; + gen_entry *combined_parent; + + /* our top-of-tree */ + gen_list *top; +}; + + +struct _gen_list +{ + model_entry *model; + insn_table *isa; + gen_entry *table; + gen_list *next; +}; + + +typedef struct _gen_table gen_table; +struct _gen_table +{ + /* list of all the instructions */ + insn_table *isa; + /* list of all the semantic functions */ + decode_table *rules; + /* list of all the generated instruction tables */ + gen_list *tables; + /* list of all the semantic functions */ + int nr_semantics; + insn_list *semantics; +}; + + +extern gen_table *make_gen_tables (insn_table *isa, decode_table *rules); + + +extern void gen_tables_expand_insns (gen_table *gen); + +extern void gen_tables_expand_semantics (gen_table *gen); + +extern int gen_entry_depth (gen_entry *table); + + + +/* Traverse the created data structure */ + +typedef void gen_entry_handler + (lf *file, gen_entry *entry, int depth, void *data); + +extern void gen_entry_traverse_tree + (lf *file, + gen_entry *table, + int depth, + gen_entry_handler * start, + gen_entry_handler * leaf, gen_entry_handler * end, void *data); + + + +/* Misc functions - actually in igen.c */ + + +/* Cache functions: */ + +extern int print_icache_function_formal (lf *file, int nr_prefetched_words); + +extern int print_icache_function_actual (lf *file, int nr_prefetched_words); + +extern int print_icache_function_type (lf *file); + +extern int print_semantic_function_formal (lf *file, int nr_prefetched_words); + +extern int print_semantic_function_actual (lf *file, int nr_prefetched_words); + +extern int print_semantic_function_type (lf *file); + +extern int print_idecode_function_formal (lf *file, int nr_prefetched_words); + +extern int print_idecode_function_actual (lf *file, int nr_prefetched_words); + +typedef enum +{ + function_name_prefix_semantics, + function_name_prefix_idecode, + function_name_prefix_itable, + function_name_prefix_icache, + function_name_prefix_engine, + function_name_prefix_none +} +lf_function_name_prefixes; + +typedef enum +{ + is_function_declaration = 0, + is_function_definition = 1, + is_function_variable, +} +function_decl_type; + +extern int print_function_name + (lf *file, + const char *basename, + const char *format_name, + const char *model_name, + opcode_bits *expanded_bits, lf_function_name_prefixes prefix); + +extern void print_my_defines + (lf *file, + const char *basename, const char *format_name, opcode_bits *expanded_bits); + +extern void print_itrace (lf *file, insn_entry * insn, int idecode); + +extern void print_sim_engine_abort (lf *file, const char *message); + + +extern void print_include (lf *file, igen_module module); +extern void print_include_inline (lf *file, igen_module module); +extern void print_includes (lf *file);
gen.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: filter_host.c =================================================================== --- filter_host.c (nonexistent) +++ filter_host.c (revision 841) @@ -0,0 +1,38 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + +#include "config.h" +#include "filter_host.h" + +/* Shorten traces by eliminating the directory component to filenames. */ +const char * +filter_filename (const char *filename) +{ + const char *p = filename; + const char *last = filename; + int ch; + + while ((ch = *p++) != '\0' && ch != ':') + if (ch == '/') + last = p; + + return last; +}
filter_host.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: igen.c =================================================================== --- igen.c (nonexistent) +++ igen.c (revision 841) @@ -0,0 +1,1662 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + + +#include + +#include "misc.h" +#include "lf.h" +#include "table.h" +#include "config.h" +#include "filter.h" + +#include "igen.h" + +#include "ld-insn.h" +#include "ld-decode.h" +#include "ld-cache.h" + +#include "gen.h" + +#include "gen-model.h" +#include "gen-icache.h" +#include "gen-itable.h" +#include "gen-idecode.h" +#include "gen-semantics.h" +#include "gen-engine.h" +#include "gen-support.h" +#include "gen-engine.h" + + +/****************************************************************/ + + +/* Semantic functions */ + +int +print_semantic_function_formal (lf *file, int nr_prefetched_words) +{ + int nr = 0; + int word_nr; + if (options.gen.icache || nr_prefetched_words < 0) + { + nr += lf_printf (file, "SIM_DESC sd,\n"); + nr += lf_printf (file, "%sidecode_cache *cache_entry,\n", + options.module.global.prefix.l); + nr += lf_printf (file, "%sinstruction_address cia", + options.module.global.prefix.l); + } + else if (options.gen.smp) + { + nr += lf_printf (file, "sim_cpu *cpu,\n"); + for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) + { + nr += lf_printf (file, "%sinstruction_word instruction_%d,\n", + options.module.global.prefix.l, word_nr); + } + nr += lf_printf (file, "%sinstruction_address cia", + options.module.global.prefix.l); + } + else + { + nr += lf_printf (file, "SIM_DESC sd,\n"); + for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) + { + nr += lf_printf (file, "%sinstruction_word instruction_%d,\n", + options.module.global.prefix.l, word_nr); + } + nr += lf_printf (file, "%sinstruction_address cia", + options.module.global.prefix.l); + } + return nr; +} + +int +print_semantic_function_actual (lf *file, int nr_prefetched_words) +{ + int nr = 0; + int word_nr; + if (options.gen.icache || nr_prefetched_words < 0) + { + nr += lf_printf (file, "sd, cache_entry, cia"); + } + else + { + if (options.gen.smp) + nr += lf_printf (file, "cpu"); + else + nr += lf_printf (file, "sd"); + for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) + nr += lf_printf (file, ", instruction_%d", word_nr); + nr += lf_printf (file, ", cia"); + } + return nr; +} + +int +print_semantic_function_type (lf *file) +{ + int nr = 0; + nr += lf_printf (file, "%sinstruction_address", + options.module.global.prefix.l); + return nr; +} + + +/* Idecode functions */ + +int +print_icache_function_formal (lf *file, int nr_prefetched_words) +{ + int nr = 0; + int word_nr; + if (options.gen.smp) + nr += lf_printf (file, "sim_cpu *cpu,\n"); + else + nr += lf_printf (file, "SIM_DESC sd,\n"); + for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) + nr += lf_printf (file, " %sinstruction_word instruction_%d,\n", + options.module.global.prefix.l, word_nr); + nr += lf_printf (file, " %sinstruction_address cia,\n", + options.module.global.prefix.l); + nr += lf_printf (file, " %sidecode_cache *cache_entry", + options.module.global.prefix.l); + return nr; +} + +int +print_icache_function_actual (lf *file, int nr_prefetched_words) +{ + int nr = 0; + int word_nr; + if (options.gen.smp) + nr += lf_printf (file, "cpu"); + else + nr += lf_printf (file, "sd"); + for (word_nr = 0; word_nr < nr_prefetched_words; word_nr++) + nr += lf_printf (file, ", instruction_%d", word_nr); + nr += lf_printf (file, ", cia, cache_entry"); + return nr; +} + +int +print_icache_function_type (lf *file) +{ + int nr; + if (options.gen.semantic_icache) + { + nr = print_semantic_function_type (file); + } + else + { + nr = lf_printf (file, "%sidecode_semantic *", + options.module.global.prefix.l); + } + return nr; +} + + +/* Function names */ + +static int +print_opcode_bits (lf *file, opcode_bits *bits) +{ + int nr = 0; + if (bits == NULL) + return nr; + nr += lf_putchr (file, '_'); + nr += lf_putstr (file, bits->field->val_string); + if (bits->opcode->is_boolean && bits->value == 0) + nr += lf_putint (file, bits->opcode->boolean_constant); + else if (!bits->opcode->is_boolean) + { + if (bits->opcode->last < bits->field->last) + nr += + lf_putint (file, + bits->value << (bits->field->last - bits->opcode->last)); + else + nr += lf_putint (file, bits->value); + } + nr += print_opcode_bits (file, bits->next); + return nr; +} + +static int +print_c_name (lf *file, const char *name) +{ + int nr = 0; + const char *pos; + for (pos = name; *pos != '\0'; pos++) + { + switch (*pos) + { + case '/': + case '-': + break; + case ' ': + case '.': + nr += lf_putchr (file, '_'); + break; + default: + nr += lf_putchr (file, *pos); + break; + } + } + return nr; +} + +extern int +print_function_name (lf *file, + const char *basename, + const char *format_name, + const char *model_name, + opcode_bits *expanded_bits, + lf_function_name_prefixes prefix) +{ + int nr = 0; + /* the prefix */ + switch (prefix) + { + case function_name_prefix_semantics: + nr += lf_printf (file, "%s", options.module.semantics.prefix.l); + nr += lf_printf (file, "semantic_"); + break; + case function_name_prefix_idecode: + nr += lf_printf (file, "%s", options.module.idecode.prefix.l); + nr += lf_printf (file, "idecode_"); + break; + case function_name_prefix_itable: + nr += lf_printf (file, "%sitable_", options.module.itable.prefix.l); + break; + case function_name_prefix_icache: + nr += lf_printf (file, "%s", options.module.icache.prefix.l); + nr += lf_printf (file, "icache_"); + break; + case function_name_prefix_engine: + nr += lf_printf (file, "%s", options.module.engine.prefix.l); + nr += lf_printf (file, "engine_"); + default: + break; + } + + if (model_name != NULL) + { + nr += print_c_name (file, model_name); + nr += lf_printf (file, "_"); + } + + /* the function name */ + nr += print_c_name (file, basename); + + /* the format name if available */ + if (format_name != NULL) + { + nr += lf_printf (file, "_"); + nr += print_c_name (file, format_name); + } + + /* the suffix */ + nr += print_opcode_bits (file, expanded_bits); + + return nr; +} + + +void +print_my_defines (lf *file, + const char *basename, + const char *format_name, opcode_bits *expanded_bits) +{ + /* #define MY_INDEX xxxxx */ + lf_indent_suppress (file); + lf_printf (file, "#undef MY_INDEX\n"); + lf_indent_suppress (file); + lf_printf (file, "#define MY_INDEX "); + print_function_name (file, + basename, format_name, NULL, + NULL, function_name_prefix_itable); + lf_printf (file, "\n"); + /* #define MY_PREFIX xxxxxx */ + lf_indent_suppress (file); + lf_printf (file, "#undef "); + print_function_name (file, + basename, format_name, NULL, + expanded_bits, function_name_prefix_none); + lf_printf (file, "\n"); + lf_indent_suppress (file); + lf_printf (file, "#undef MY_PREFIX\n"); + lf_indent_suppress (file); + lf_printf (file, "#define MY_PREFIX "); + print_function_name (file, + basename, format_name, NULL, + expanded_bits, function_name_prefix_none); + lf_printf (file, "\n"); + /* #define MY_NAME xxxxxx */ + lf_indent_suppress (file); + lf_indent_suppress (file); + lf_printf (file, "#undef MY_NAME\n"); + lf_indent_suppress (file); + lf_printf (file, "#define MY_NAME \""); + print_function_name (file, + basename, format_name, NULL, + expanded_bits, function_name_prefix_none); + lf_printf (file, "\"\n"); +} + + +static int +print_itrace_prefix (lf *file) +{ + const char *prefix = "trace_prefix ("; + int indent = strlen (prefix); + lf_printf (file, "%sSD, CPU, cia, CIA, TRACE_LINENUM_P (CPU), \\\n", + prefix); + lf_indent (file, +indent); + lf_printf (file, "%sitable[MY_INDEX].file, \\\n", + options.module.itable.prefix.l); + lf_printf (file, "%sitable[MY_INDEX].line_nr, \\\n", + options.module.itable.prefix.l); + lf_printf (file, "\""); + return indent; +} + + +static void +print_itrace_format (lf *file, insn_mnemonic_entry *assembler) +{ + /* pass=1 is fmt string; pass=2 is arguments */ + int pass; + /* print the format string */ + for (pass = 1; pass <= 2; pass++) + { + const char *chp = assembler->format; + chp++; /* skip the leading quote */ + /* write out the format/args */ + while (*chp != '\0') + { + if (chp[0] == '\\' && (chp[1] == '<' || chp[1] == '>')) + { + if (pass == 1) + lf_putchr (file, chp[1]); + chp += 2; + } + else if (chp[0] == '<' || chp[0] == '%') + { + /* parse [ "%" ... ] "<" [ func "#" ] param ">" */ + const char *fmt; + const char *func; + int strlen_func; + const char *param; + int strlen_param; + /* the "%" ... "<" format */ + fmt = chp; + while (chp[0] != '<' && chp[0] != '\0') + chp++; + if (chp[0] != '<') + error (assembler->line, "Missing `<' after `%%'\n"); + chp++; + /* [ "func" # ] OR "param" */ + func = chp; + param = chp; + while (chp[0] != '>' && chp[0] != '#' && chp[0] != '\0') + chp++; + strlen_func = chp - func; + if (chp[0] == '#') + { + chp++; + param = chp; + while (chp[0] != '>' && chp[0] != '\0') + chp++; + } + strlen_param = chp - param; + if (chp[0] != '>') + error (assembler->line, + "Missing closing `>' in assembler string\n"); + chp++; + /* now process it */ + if (pass == 2) + lf_printf (file, ", \\\n"); + if (strncmp (fmt, "<", 1) == 0) + /* implicit long int format */ + { + if (pass == 1) + lf_printf (file, "%%ld"); + else + { + lf_printf (file, "(long) "); + lf_write (file, param, strlen_param); + } + } + else if (strncmp (fmt, "%<", 2) == 0) + /* explicit format */ + { + if (pass == 1) + lf_printf (file, "%%"); + else + lf_write (file, param, strlen_param); + } + else if (strncmp (fmt, "%s<", 3) == 0) + /* string format */ + { + if (pass == 1) + lf_printf (file, "%%s"); + else + { + lf_printf (file, "%sstr_", + options.module.global.prefix.l); + lf_write (file, func, strlen_func); + lf_printf (file, " (SD_, "); + lf_write (file, param, strlen_param); + lf_printf (file, ")"); + } + } + else if (strncmp (fmt, "%lx<", 4) == 0) + /* simple hex */ + { + if (pass == 1) + lf_printf (file, "%%lx"); + else + { + lf_printf (file, "(unsigned long) "); + lf_write (file, param, strlen_param); + } + } + else if (strncmp (fmt, "%#lx<", 5) == 0) + /* simple hex with 0x prefix */ + { + if (pass == 1) + lf_printf (file, "%%#lx"); + else + { + lf_printf (file, "(unsigned long) "); + lf_write (file, param, strlen_param); + } + } + else if (strncmp (fmt, "%08lx<", 6) == 0) + /* simple hex */ + { + if (pass == 1) + lf_printf (file, "%%08lx"); + else + { + lf_printf (file, "(unsigned long) "); + lf_write (file, param, strlen_param); + } + } + else + error (assembler->line, "Unknown assembler string format\n"); + } + else + { + if (pass == 1) + lf_putchr (file, chp[0]); + chp += 1; + } + } + } + lf_printf (file, ");\n"); +} + + +void +print_itrace (lf *file, insn_entry * insn, int idecode) +{ + /* NB: Here we escape each EOLN. This is so that the the compiler + treats a trace function call as a single line. Consequently any + errors in the line are refered back to the same igen assembler + source line */ + const char *phase = (idecode) ? "DECODE" : "INSN"; + lf_printf (file, "\n"); + lf_indent_suppress (file); + lf_printf (file, "#if defined (WITH_TRACE)\n"); + lf_printf (file, "/* generate a trace prefix if any tracing enabled */\n"); + lf_printf (file, "if (TRACE_ANY_P (CPU))\n"); + lf_printf (file, " {\n"); + lf_indent (file, +4); + { + if (insn->mnemonics != NULL) + { + insn_mnemonic_entry *assembler = insn->mnemonics; + int is_first = 1; + do + { + if (assembler->condition != NULL) + { + int indent; + lf_printf (file, "%sif (%s)\n", + is_first ? "" : "else ", assembler->condition); + lf_indent (file, +2); + lf_print__line_ref (file, assembler->line); + indent = print_itrace_prefix (file); + print_itrace_format (file, assembler); + lf_print__internal_ref (file); + lf_indent (file, -indent); + lf_indent (file, -2); + if (assembler->next == NULL) + error (assembler->line, + "Missing final unconditional assembler\n"); + } + else + { + int indent; + if (!is_first) + { + lf_printf (file, "else\n"); + lf_indent (file, +2); + } + lf_print__line_ref (file, assembler->line); + indent = print_itrace_prefix (file); + print_itrace_format (file, assembler); + lf_print__internal_ref (file); + lf_indent (file, -indent); + if (!is_first) + lf_indent (file, -2); + if (assembler->next != NULL) + error (assembler->line, + "Unconditional assembler is not last\n"); + } + is_first = 0; + assembler = assembler->next; + } + while (assembler != NULL); + } + else + { + int indent; + lf_indent (file, +2); + lf_print__line_ref (file, insn->line); + indent = print_itrace_prefix (file); + lf_printf (file, "%%s\", \\\n"); + lf_printf (file, "itable[MY_INDEX].name);\n"); + lf_print__internal_ref (file); + lf_indent (file, -indent); + lf_indent (file, -2); + } + lf_printf (file, "/* trace the instruction execution if enabled */\n"); + lf_printf (file, "if (TRACE_%s_P (CPU))\n", phase); + lf_printf (file, + " trace_generic (SD, CPU, TRACE_%s_IDX, \" %%s\", itable[MY_INDEX].name);\n", + phase); + } + lf_indent (file, -4); + lf_printf (file, " }\n"); + lf_indent_suppress (file); + lf_printf (file, "#endif\n"); +} + + +void +print_sim_engine_abort (lf *file, const char *message) +{ + lf_printf (file, "sim_engine_abort (SD, CPU, cia, "); + lf_printf (file, "\"%s\"", message); + lf_printf (file, ");\n"); +} + + +void +print_include (lf *file, igen_module module) +{ + lf_printf (file, "#include \"%s%s.h\"\n", module.prefix.l, module.suffix.l); +} + +void +print_include_inline (lf *file, igen_module module) +{ + lf_printf (file, "#if C_REVEALS_MODULE_P (%s_INLINE)\n", module.suffix.u); + lf_printf (file, "#include \"%s%s.c\"\n", module.prefix.l, module.suffix.l); + lf_printf (file, "#else\n"); + print_include (file, module); + lf_printf (file, "#endif\n"); + lf_printf (file, "\n"); +} + +void +print_includes (lf *file) +{ + lf_printf (file, "\n"); + lf_printf (file, "#include \"sim-inline.c\"\n"); + lf_printf (file, "\n"); + print_include_inline (file, options.module.itable); + print_include_inline (file, options.module.idecode); + print_include_inline (file, options.module.support); +} + + +/****************************************************************/ + + +static void +gen_semantics_h (lf *file, insn_list *semantics, int max_nr_words) +{ + int word_nr; + insn_list *semantic; + for (word_nr = -1; word_nr <= max_nr_words; word_nr++) + { + lf_printf (file, "typedef "); + print_semantic_function_type (file); + lf_printf (file, " %sidecode_semantic", options.module.global.prefix.l); + if (word_nr >= 0) + lf_printf (file, "_%d", word_nr); + lf_printf (file, "\n("); + lf_indent (file, +1); + print_semantic_function_formal (file, word_nr); + lf_indent (file, -1); + lf_printf (file, ");\n"); + lf_printf (file, "\n"); + } + switch (options.gen.code) + { + case generate_calls: + for (semantic = semantics; semantic != NULL; semantic = semantic->next) + { + /* Ignore any special/internal instructions */ + if (semantic->insn->nr_words == 0) + continue; + print_semantic_declaration (file, + semantic->insn, + semantic->expanded_bits, + semantic->opcodes, + semantic->nr_prefetched_words); + } + break; + case generate_jumps: + lf_print__this_file_is_empty (file, "generating jumps"); + break; + } +} + + +static void +gen_semantics_c (lf *file, insn_list *semantics, cache_entry *cache_rules) +{ + if (options.gen.code == generate_calls) + { + insn_list *semantic; + print_includes (file); + print_include (file, options.module.semantics); + lf_printf (file, "\n"); + + for (semantic = semantics; semantic != NULL; semantic = semantic->next) + { + /* Ignore any special/internal instructions */ + if (semantic->insn->nr_words == 0) + continue; + print_semantic_definition (file, + semantic->insn, + semantic->expanded_bits, + semantic->opcodes, + cache_rules, + semantic->nr_prefetched_words); + } + } + else + { + lf_print__this_file_is_empty (file, "generating jump engine"); + } +} + + +/****************************************************************/ + + +static void +gen_icache_h (lf *file, + insn_list *semantic, + function_entry * functions, int max_nr_words) +{ + int word_nr; + for (word_nr = 0; word_nr <= max_nr_words; word_nr++) + { + lf_printf (file, "typedef "); + print_icache_function_type (file); + lf_printf (file, " %sidecode_icache_%d\n(", + options.module.global.prefix.l, word_nr); + print_icache_function_formal (file, word_nr); + lf_printf (file, ");\n"); + lf_printf (file, "\n"); + } + if (options.gen.code == generate_calls && options.gen.icache) + { + function_entry_traverse (file, functions, + print_icache_internal_function_declaration, + NULL); + while (semantic != NULL) + { + print_icache_declaration (file, + semantic->insn, + semantic->expanded_bits, + semantic->opcodes, + semantic->nr_prefetched_words); + semantic = semantic->next; + } + } + else + { + lf_print__this_file_is_empty (file, "generating jump engine"); + } +} + +static void +gen_icache_c (lf *file, + insn_list *semantic, + function_entry * functions, cache_entry *cache_rules) +{ + /* output `internal' invalid/floating-point unavailable functions + where needed */ + if (options.gen.code == generate_calls && options.gen.icache) + { + lf_printf (file, "\n"); + lf_printf (file, "#include \"cpu.h\"\n"); + lf_printf (file, "#include \"idecode.h\"\n"); + lf_printf (file, "#include \"semantics.h\"\n"); + lf_printf (file, "#include \"icache.h\"\n"); + lf_printf (file, "#include \"support.h\"\n"); + lf_printf (file, "\n"); + function_entry_traverse (file, functions, + print_icache_internal_function_definition, + NULL); + lf_printf (file, "\n"); + while (semantic != NULL) + { + print_icache_definition (file, + semantic->insn, + semantic->expanded_bits, + semantic->opcodes, + cache_rules, + semantic->nr_prefetched_words); + semantic = semantic->next; + } + } + else + { + lf_print__this_file_is_empty (file, "generating jump engine"); + } +} + + +/****************************************************************/ + + +static void +gen_idecode_h (lf *file, + gen_table *gen, insn_table *insns, cache_entry *cache_rules) +{ + lf_printf (file, "typedef unsigned%d %sinstruction_word;\n", + options.insn_bit_size, options.module.global.prefix.l); + if (options.gen.delayed_branch) + { + lf_printf (file, "typedef struct _%sinstruction_address {\n", + options.module.global.prefix.l); + lf_printf (file, " address_word ip; /* instruction pointer */\n"); + lf_printf (file, " address_word dp; /* delayed-slot pointer */\n"); + lf_printf (file, "} %sinstruction_address;\n", + options.module.global.prefix.l); + } + else + { + lf_printf (file, "typedef address_word %sinstruction_address;\n", + options.module.global.prefix.l); + + } + if (options.gen.nia == nia_is_invalid + && strlen (options.module.global.prefix.u) > 0) + { + lf_indent_suppress (file); + lf_printf (file, "#define %sINVALID_INSTRUCTION_ADDRESS ", + options.module.global.prefix.u); + lf_printf (file, "INVALID_INSTRUCTION_ADDRESS\n"); + } + lf_printf (file, "\n"); + print_icache_struct (file, insns, cache_rules); + lf_printf (file, "\n"); + if (options.gen.icache) + { + ERROR ("FIXME - idecode with icache suffering from bit-rot"); + } + else + { + gen_list *entry; + for (entry = gen->tables; entry != NULL; entry = entry->next) + { + print_idecode_issue_function_header (file, + (options.gen.multi_sim + ? entry->model->name + : NULL), + is_function_declaration, + 1 /*ALWAYS ONE WORD */ ); + } + if (options.gen.multi_sim) + { + print_idecode_issue_function_header (file, + NULL, + is_function_variable, + 1 /*ALWAYS ONE WORD */ ); + } + } +} + + +static void +gen_idecode_c (lf *file, + gen_table *gen, insn_table *isa, cache_entry *cache_rules) +{ + /* the intro */ + print_includes (file); + print_include_inline (file, options.module.semantics); + lf_printf (file, "\n"); + + print_idecode_globals (file); + lf_printf (file, "\n"); + + switch (options.gen.code) + { + case generate_calls: + { + gen_list *entry; + for (entry = gen->tables; entry != NULL; entry = entry->next) + { + print_idecode_lookups (file, entry->table, cache_rules); + + /* output the main idecode routine */ + if (!options.gen.icache) + { + print_idecode_issue_function_header (file, + (options.gen.multi_sim + ? entry->model->name + : NULL), + 1 /*is definition */ , + 1 /*ALWAYS ONE WORD */ ); + lf_printf (file, "{\n"); + lf_indent (file, +2); + lf_printf (file, "%sinstruction_address nia;\n", + options.module.global.prefix.l); + print_idecode_body (file, entry->table, "nia ="); + lf_printf (file, "return nia;"); + lf_indent (file, -2); + lf_printf (file, "}\n"); + } + } + break; + } + case generate_jumps: + { + lf_print__this_file_is_empty (file, "generating a jump engine"); + break; + } + } +} + + +/****************************************************************/ + + +static void +gen_run_c (lf *file, gen_table *gen) +{ + gen_list *entry; + lf_printf (file, "#include \"sim-main.h\"\n"); + lf_printf (file, "#include \"engine.h\"\n"); + lf_printf (file, "#include \"idecode.h\"\n"); + lf_printf (file, "#include \"bfd.h\"\n"); + lf_printf (file, "\n"); + + if (options.gen.multi_sim) + { + print_idecode_issue_function_header (file, NULL, is_function_variable, + 1); + lf_printf (file, "\n"); + print_engine_run_function_header (file, NULL, is_function_variable); + lf_printf (file, "\n"); + } + + lf_printf (file, "void\n"); + lf_printf (file, "sim_engine_run (SIM_DESC sd,\n"); + lf_printf (file, " int next_cpu_nr,\n"); + lf_printf (file, " int nr_cpus,\n"); + lf_printf (file, " int siggnal)\n"); + lf_printf (file, "{\n"); + lf_indent (file, +2); + if (options.gen.multi_sim) + { + lf_printf (file, "int mach;\n"); + lf_printf (file, "if (STATE_ARCHITECTURE (sd) == NULL)\n"); + lf_printf (file, " mach = 0;\n"); + lf_printf (file, "else\n"); + lf_printf (file, " mach = STATE_ARCHITECTURE (sd)->mach;\n"); + lf_printf (file, "switch (mach)\n"); + lf_printf (file, " {\n"); + lf_indent (file, +2); + for (entry = gen->tables; entry != NULL; entry = entry->next) + { + if (options.gen.default_model != NULL + && (strcmp (entry->model->name, options.gen.default_model) == 0 + || strcmp (entry->model->full_name, + options.gen.default_model) == 0)) + lf_printf (file, "default:\n"); + lf_printf (file, "case bfd_mach_%s:\n", entry->model->full_name); + lf_indent (file, +2); + print_function_name (file, "issue", NULL, /* format name */ + NULL, /* NO processor */ + NULL, /* expanded bits */ + function_name_prefix_idecode); + lf_printf (file, " = "); + print_function_name (file, "issue", NULL, /* format name */ + entry->model->name, NULL, /* expanded bits */ + function_name_prefix_idecode); + lf_printf (file, ";\n"); + print_function_name (file, "run", NULL, /* format name */ + NULL, /* NO processor */ + NULL, /* expanded bits */ + function_name_prefix_engine); + lf_printf (file, " = "); + print_function_name (file, "run", NULL, /* format name */ + entry->model->name, NULL, /* expanded bits */ + function_name_prefix_engine); + lf_printf (file, ";\n"); + lf_printf (file, "break;\n"); + lf_indent (file, -2); + } + if (options.gen.default_model == NULL) + { + lf_printf (file, "default:\n"); + lf_indent (file, +2); + lf_printf (file, "sim_engine_abort (sd, NULL, NULL_CIA,\n"); + lf_printf (file, + " \"sim_engine_run - unknown machine\");\n"); + lf_printf (file, "break;\n"); + lf_indent (file, -2); + } + lf_indent (file, -2); + lf_printf (file, " }\n"); + } + print_function_name (file, "run", NULL, /* format name */ + NULL, /* NO processor */ + NULL, /* expanded bits */ + function_name_prefix_engine); + lf_printf (file, " (sd, next_cpu_nr, nr_cpus, siggnal);\n"); + lf_indent (file, -2); + lf_printf (file, "}\n"); +} + +/****************************************************************/ + +static gen_table * +do_gen (insn_table *isa, decode_table *decode_rules) +{ + gen_table *gen; + if (decode_rules == NULL) + error (NULL, "Must specify a decode table\n"); + if (isa == NULL) + error (NULL, "Must specify an instruction table\n"); + if (decode_table_max_word_nr (decode_rules) > 0) + options.gen.multi_word = decode_table_max_word_nr (decode_rules); + gen = make_gen_tables (isa, decode_rules); + gen_tables_expand_insns (gen); + gen_tables_expand_semantics (gen); + return gen; +} + +/****************************************************************/ + +igen_options options; + +int +main (int argc, char **argv, char **envp) +{ + cache_entry *cache_rules = NULL; + lf_file_references file_references = lf_include_references; + decode_table *decode_rules = NULL; + insn_table *isa = NULL; + gen_table *gen = NULL; + char *real_file_name = NULL; + int is_header = 0; + int ch; + lf *standard_out = + lf_open ("-", "stdout", lf_omit_references, lf_is_text, "igen"); + + INIT_OPTIONS (); + + if (argc == 1) + { + printf ("Usage:\n"); + printf ("\n"); + printf (" igen ... ... ...\n"); + printf ("\n"); + printf ("Config options:\n"); + printf ("\n"); + printf (" -B \n"); + printf ("\t Set the number of bits in an instruction (deprecated).\n"); + printf + ("\t This option can now be set directly in the instruction table.\n"); + printf ("\n"); + printf (" -D \n"); + printf + ("\t Dump the specified data structure to stdout. Valid structures include:\n"); + printf + ("\t processor-names - list the names of all the processors (models)\n"); + printf ("\n"); + printf (" -F \n"); + printf + ("\t Filter out any instructions with a non-empty flags field that contains\n"); + printf ("\t a flag not listed in the .\n"); + printf ("\n"); + printf (" -H \n"); + printf + ("\t Set the number of the high (most significant) instruction bit (deprecated).\n"); + printf + ("\t This option can now be set directly in the instruction table.\n"); + printf ("\n"); + printf (" -I \n"); + printf + ("\t Add to the list of directories searched when opening a file\n"); + printf ("\n"); + printf (" -M \n"); + printf + ("\t Filter out any instructions that do not support at least one of the listed\n"); + printf + ("\t models (An instructions with no model information is considered to support\n"); + printf ("\t all models.).\n"); + printf ("\n"); + printf (" -N \n"); + printf ("\t Generate a simulator supporting \n"); + printf + ("\t Specify `-N 0' to disable generation of the SMP. Specifying `-N 1' will\n"); + printf + ("\t still generate an SMP enabled simulator but will only support one CPU.\n"); + printf ("\n"); + printf (" -T \n"); + printf + ("\t Override the decode mechanism specified by the decode rules\n"); + printf ("\n"); + printf (" -P \n"); + printf + ("\t Prepend global names (except itable) with the string .\n"); + printf + ("\t Specify -P = to set a specific 's prefix.\n"); + printf ("\n"); + printf (" -S \n"); + printf + ("\t Replace a global name (suffix) (except itable) with the string .\n"); + printf + ("\t Specify -S = to change a specific 's name (suffix).\n"); + printf ("\n"); + printf (" -Werror\n"); + printf ("\t Make warnings errors\n"); + printf (" -Wnodiscard\n"); + printf + ("\t Suppress warnings about discarded functions and instructions\n"); + printf (" -Wnowidth\n"); + printf + ("\t Suppress warnings about instructions with invalid widths\n"); + printf (" -Wnounimplemented\n"); + printf ("\t Suppress warnings about unimplemented instructions\n"); + printf ("\n"); + printf (" -G [!]\n"); + printf ("\t Any of the following options:\n"); + printf ("\n"); + printf + ("\t decode-duplicate - Override the decode rules, forcing the duplication of\n"); + printf ("\t semantic functions\n"); + printf + ("\t decode-combine - Combine any duplicated entries within a table\n"); + printf + ("\t decode-zero-reserved - Override the decode rules, forcing reserved bits to be\n"); + printf ("\t treated as zero.\n"); + printf + ("\t decode-switch-is-goto - Overfide the padded-switch code type as a goto-switch\n"); + printf ("\n"); + printf + ("\t gen-conditional-issue - conditionally issue each instruction\n"); + printf + ("\t gen-delayed-branch - need both cia and nia passed around\n"); + printf + ("\t gen-direct-access - use #defines to directly access values\n"); + printf + ("\t gen-zero-r - arch assumes GPR() == 0, keep it that way\n"); + printf + ("\t gen-icache[= - generate an instruction cracking cache of size \n"); + printf ("\t Default size is %d\n", + options.gen.icache_size); + printf + ("\t gen-insn-in-icache - save original instruction when cracking\n"); + printf + ("\t gen-multi-sim[=MODEL] - generate multiple simulators - one per model\n"); + printf + ("\t If specified MODEL is made the default architecture.\n"); + printf + ("\t By default, a single simulator that will\n"); + printf + ("\t execute any instruction is generated\n"); + printf + ("\t gen-multi-word - generate code allowing for multi-word insns\n"); + printf + ("\t gen-semantic-icache - include semantic code in cracking functions\n"); + printf + ("\t gen-slot-verification - perform slot verification as part of decode\n"); + printf ("\t gen-nia-invalid - NIA defaults to nia_invalid\n"); + printf ("\t gen-nia-void - do not compute/return NIA\n"); + printf ("\n"); + printf + ("\t trace-combine - report combined entries a rule application\n"); + printf + ("\t trace-entries - report entries after a rules application\n"); + printf ("\t trace-rule-rejection - report each rule as rejected\n"); + printf ("\t trace-rule-selection - report each rule as selected\n"); + printf + ("\t trace-insn-insertion - report each instruction as it is inserted into a decode table\n"); + printf + ("\t trace-rule-expansion - report each instruction as it is expanded (before insertion into a decode table)\n"); + printf ("\t trace-all - enable all trace options\n"); + printf ("\n"); + printf + ("\t field-widths - instruction formats specify widths (deprecated)\n"); + printf + ("\t By default, an instruction format specifies bit\n"); + printf ("\t positions\n"); + printf + ("\t This option can now be set directly in the\n"); + printf ("\t instruction table\n"); + printf + ("\t jumps - use jumps instead of function calls\n"); + printf + ("\t omit-line-numbers - do not include line number information in the output\n"); + printf ("\n"); + printf ("Input options:\n"); + printf ("\n"); + printf (" -k (deprecated)\n"); + printf (" -o \n"); + printf (" -i \n"); + printf ("\n"); + printf ("Output options:\n"); + printf ("\n"); + printf (" -x Perform expansion (required)\n"); + printf + (" -n Specify the real name of the next output file\n"); + printf + (" -h Generate the header (.h) file rather than the body (.c)\n"); + printf (" -c output icache\n"); + printf (" -d output idecode\n"); + printf (" -e output engine\n"); + printf (" -f output support functions\n"); + printf (" -m output model\n"); + printf (" -r output multi-sim run\n"); + printf (" -s output schematic\n"); + printf (" -t output itable\n"); + } + + while ((ch = getopt (argc, argv, + "B:D:F:G:H:I:M:N:P:T:W:o:k:i:n:hc:d:e:m:r:s:t:f:x")) + != -1) + { + fprintf (stderr, " -%c ", ch); + if (optarg) + fprintf (stderr, "%s ", optarg); + fprintf (stderr, "\\\n"); + + switch (ch) + { + + case 'M': + filter_parse (&options.model_filter, optarg); + break; + + case 'D': + if (strcmp (optarg, "processor-names")) + { + char *processor; + for (processor = filter_next (options.model_filter, ""); + processor != NULL; + processor = filter_next (options.model_filter, processor)) + lf_printf (standard_out, "%s\n", processor); + } + else + error (NULL, "Unknown data structure %s, not dumped\n", optarg); + break; + + case 'F': + filter_parse (&options.flags_filter, optarg); + break; + + case 'I': + { + table_include **dir = &options.include; + while ((*dir) != NULL) + dir = &(*dir)->next; + (*dir) = ZALLOC (table_include); + (*dir)->dir = strdup (optarg); + } + break; + + case 'B': + options.insn_bit_size = a2i (optarg); + if (options.insn_bit_size <= 0 + || options.insn_bit_size > max_insn_bit_size) + { + error (NULL, "Instruction bitsize must be in range 1..%d\n", + max_insn_bit_size); + } + if (options.hi_bit_nr != options.insn_bit_size - 1 + && options.hi_bit_nr != 0) + { + error (NULL, "Conflict betweem hi-bit-nr and insn-bit-size\n"); + } + break; + + case 'H': + options.hi_bit_nr = a2i (optarg); + if (options.hi_bit_nr != options.insn_bit_size - 1 + && options.hi_bit_nr != 0) + { + error (NULL, "Conflict between hi-bit-nr and insn-bit-size\n"); + } + break; + + case 'N': + options.gen.smp = a2i (optarg); + break; + + case 'P': + case 'S': + { + igen_module *names; + igen_name *name; + char *chp; + chp = strchr (optarg, '='); + if (chp == NULL) + { + names = &options.module.global; + chp = optarg; + } + else + { + chp = chp + 1; /* skip `=' */ + names = NULL; + if (strncmp (optarg, "global=", chp - optarg) == 0) + { + names = &options.module.global; + } + if (strncmp (optarg, "engine=", chp - optarg) == 0) + { + names = &options.module.engine; + } + if (strncmp (optarg, "icache=", chp - optarg) == 0) + { + names = &options.module.icache; + } + if (strncmp (optarg, "idecode=", chp - optarg) == 0) + { + names = &options.module.idecode; + } + if (strncmp (optarg, "itable=", chp - optarg) == 0) + { + names = &options.module.itable; + } + if (strncmp (optarg, "semantics=", chp - optarg) == 0) + { + names = &options.module.semantics; + } + if (strncmp (optarg, "support=", chp - optarg) == 0) + { + names = &options.module.support; + } + if (names == NULL) + { + error (NULL, "Prefix `%s' unreconized\n", optarg); + } + } + switch (ch) + { + case 'P': + name = &names->prefix; + break; + case 'S': + name = &names->suffix; + break; + default: + abort (); /* Bad switch. */ + } + name->u = strdup (chp); + name->l = strdup (chp); + chp = name->u; + while (*chp) + { + if (islower (*chp)) + *chp = toupper (*chp); + chp++; + } + if (name == &options.module.global.prefix) + { + options.module.engine.prefix = options.module.global.prefix; + options.module.icache.prefix = options.module.global.prefix; + options.module.idecode.prefix = options.module.global.prefix; + /* options.module.itable.prefix = options.module.global.prefix; */ + options.module.semantics.prefix = + options.module.global.prefix; + options.module.support.prefix = options.module.global.prefix; + } + if (name == &options.module.global.suffix) + { + options.module.engine.suffix = options.module.global.suffix; + options.module.icache.suffix = options.module.global.suffix; + options.module.idecode.suffix = options.module.global.suffix; + /* options.module.itable.suffix = options.module.global.suffix; */ + options.module.semantics.suffix = + options.module.global.suffix; + options.module.support.suffix = options.module.global.suffix; + } + break; + } + + case 'W': + { + if (strcmp (optarg, "error") == 0) + options.warning = error; + else if (strcmp (optarg, "nodiscard") == 0) + options.warn.discard = 0; + else if (strcmp (optarg, "discard") == 0) + options.warn.discard = 1; + else if (strcmp (optarg, "nowidth") == 0) + options.warn.width = 0; + else if (strcmp (optarg, "width") == 0) + options.warn.width = 1; + else if (strcmp (optarg, "nounimplemented") == 0) + options.warn.unimplemented = 0; + else if (strcmp (optarg, "unimplemented") == 0) + options.warn.unimplemented = 1; + else + error (NULL, "Unknown -W argument `%s'\n", optarg); + break; + } + + + case 'G': + { + int enable_p; + char *argp; + if (strncmp (optarg, "no-", strlen ("no-")) == 0) + { + argp = optarg + strlen ("no-"); + enable_p = 0; + } + else if (strncmp (optarg, "!", strlen ("!")) == 0) + { + argp = optarg + strlen ("no-"); + enable_p = 0; + } + else + { + argp = optarg; + enable_p = 1; + } + if (strcmp (argp, "decode-duplicate") == 0) + { + options.decode.duplicate = enable_p; + } + else if (strcmp (argp, "decode-combine") == 0) + { + options.decode.combine = enable_p; + } + else if (strcmp (argp, "decode-zero-reserved") == 0) + { + options.decode.zero_reserved = enable_p; + } + + else if (strcmp (argp, "gen-conditional-issue") == 0) + { + options.gen.conditional_issue = enable_p; + } + else if (strcmp (argp, "conditional-issue") == 0) + { + options.gen.conditional_issue = enable_p; + options.warning (NULL, + "Option conditional-issue replaced by gen-conditional-issue\n"); + } + else if (strcmp (argp, "gen-delayed-branch") == 0) + { + options.gen.delayed_branch = enable_p; + } + else if (strcmp (argp, "delayed-branch") == 0) + { + options.gen.delayed_branch = enable_p; + options.warning (NULL, + "Option delayed-branch replaced by gen-delayed-branch\n"); + } + else if (strcmp (argp, "gen-direct-access") == 0) + { + options.gen.direct_access = enable_p; + } + else if (strcmp (argp, "direct-access") == 0) + { + options.gen.direct_access = enable_p; + options.warning (NULL, + "Option direct-access replaced by gen-direct-access\n"); + } + else if (strncmp (argp, "gen-zero-r", strlen ("gen-zero-r")) == 0) + { + options.gen.zero_reg = enable_p; + options.gen.zero_reg_nr = atoi (argp + strlen ("gen-zero-r")); + } + else if (strncmp (argp, "zero-r", strlen ("zero-r")) == 0) + { + options.gen.zero_reg = enable_p; + options.gen.zero_reg_nr = atoi (argp + strlen ("zero-r")); + options.warning (NULL, + "Option zero-r replaced by gen-zero-r\n"); + } + else if (strncmp (argp, "gen-icache", strlen ("gen-icache")) == 0) + { + switch (argp[strlen ("gen-icache")]) + { + case '=': + options.gen.icache_size = + atoi (argp + strlen ("gen-icache") + 1); + options.gen.icache = enable_p; + break; + case '\0': + options.gen.icache = enable_p; + break; + default: + error (NULL, + "Expecting -Ggen-icache or -Ggen-icache=\n"); + } + } + else if (strcmp (argp, "gen-insn-in-icache") == 0) + { + options.gen.insn_in_icache = enable_p; + } + else if (strncmp (argp, "gen-multi-sim", strlen ("gen-multi-sim")) + == 0) + { + char *arg = &argp[strlen ("gen-multi-sim")]; + switch (arg[0]) + { + case '=': + options.gen.multi_sim = enable_p; + options.gen.default_model = arg + 1; + if (!filter_is_member + (options.model_filter, options.gen.default_model)) + error (NULL, "multi-sim model %s unknown\n", + options.gen.default_model); + break; + case '\0': + options.gen.multi_sim = enable_p; + options.gen.default_model = NULL; + break; + default: + error (NULL, + "Expecting -Ggen-multi-sim or -Ggen-multi-sim=\n"); + break; + } + } + else if (strcmp (argp, "gen-multi-word") == 0) + { + options.gen.multi_word = enable_p; + } + else if (strcmp (argp, "gen-semantic-icache") == 0) + { + options.gen.semantic_icache = enable_p; + } + else if (strcmp (argp, "gen-slot-verification") == 0) + { + options.gen.slot_verification = enable_p; + } + else if (strcmp (argp, "verify-slot") == 0) + { + options.gen.slot_verification = enable_p; + options.warning (NULL, + "Option verify-slot replaced by gen-slot-verification\n"); + } + else if (strcmp (argp, "gen-nia-invalid") == 0) + { + options.gen.nia = nia_is_invalid; + } + else if (strcmp (argp, "default-nia-minus-one") == 0) + { + options.gen.nia = nia_is_invalid; + options.warning (NULL, + "Option default-nia-minus-one replaced by gen-nia-invalid\n"); + } + else if (strcmp (argp, "gen-nia-void") == 0) + { + options.gen.nia = nia_is_void; + } + else if (strcmp (argp, "trace-all") == 0) + { + memset (&options.trace, enable_p, sizeof (options.trace)); + } + else if (strcmp (argp, "trace-combine") == 0) + { + options.trace.combine = enable_p; + } + else if (strcmp (argp, "trace-entries") == 0) + { + options.trace.entries = enable_p; + } + else if (strcmp (argp, "trace-rule-rejection") == 0) + { + options.trace.rule_rejection = enable_p; + } + else if (strcmp (argp, "trace-rule-selection") == 0) + { + options.trace.rule_selection = enable_p; + } + else if (strcmp (argp, "trace-insn-insertion") == 0) + { + options.trace.insn_insertion = enable_p; + } + else if (strcmp (argp, "trace-insn-expansion") == 0) + { + options.trace.insn_expansion = enable_p; + } + else if (strcmp (argp, "jumps") == 0) + { + options.gen.code = generate_jumps; + } + else if (strcmp (argp, "field-widths") == 0) + { + options.insn_specifying_widths = enable_p; + } + else if (strcmp (argp, "omit-line-numbers") == 0) + { + file_references = lf_omit_references; + } + else + { + error (NULL, "Unknown option %s\n", optarg); + } + break; + } + + case 'i': + isa = load_insn_table (optarg, cache_rules); + if (isa->illegal_insn == NULL) + error (NULL, "illegal-instruction missing from insn table\n"); + break; + + case 'x': + gen = do_gen (isa, decode_rules); + break; + + case 'o': + decode_rules = load_decode_table (optarg); + break; + + case 'k': + if (isa != NULL) + error (NULL, "Cache file must appear before the insn file\n"); + cache_rules = load_cache_table (optarg); + break; + + case 'n': + real_file_name = strdup (optarg); + break; + + case 'h': + is_header = 1; + break; + + case 'c': + case 'd': + case 'e': + case 'f': + case 'm': + case 'r': + case 's': + case 't': + { + lf *file = lf_open (optarg, real_file_name, file_references, + (is_header ? lf_is_h : lf_is_c), + argv[0]); + if (gen == NULL && ch != 't' && ch != 'm' && ch != 'f') + { + options.warning (NULL, + "Explicitly generate tables with -x option\n"); + gen = do_gen (isa, decode_rules); + } + lf_print__file_start (file); + switch (ch) + { + case 'm': + if (is_header) + gen_model_h (file, isa); + else + gen_model_c (file, isa); + break; + case 't': + if (is_header) + gen_itable_h (file, isa); + else + gen_itable_c (file, isa); + break; + case 'f': + if (is_header) + gen_support_h (file, isa); + else + gen_support_c (file, isa); + break; + case 'r': + if (is_header) + options.warning (NULL, "-hr option ignored\n"); + else + gen_run_c (file, gen); + break; + case 's': + if (is_header) + gen_semantics_h (file, gen->semantics, isa->max_nr_words); + else + gen_semantics_c (file, gen->semantics, isa->caches); + break; + case 'd': + if (is_header) + gen_idecode_h (file, gen, isa, cache_rules); + else + gen_idecode_c (file, gen, isa, cache_rules); + break; + case 'e': + if (is_header) + gen_engine_h (file, gen, isa, cache_rules); + else + gen_engine_c (file, gen, isa, cache_rules); + break; + case 'c': + if (is_header) + gen_icache_h (file, + gen->semantics, + isa->functions, isa->max_nr_words); + else + gen_icache_c (file, + gen->semantics, isa->functions, cache_rules); + break; + } + lf_print__file_finish (file); + lf_close (file); + is_header = 0; + } + real_file_name = NULL; + break; + default: + ERROR ("Bad switch"); + } + } + return (0); +}
igen.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen-icache.c =================================================================== --- gen-icache.c (nonexistent) +++ gen-icache.c (revision 841) @@ -0,0 +1,818 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +#include "misc.h" +#include "lf.h" +#include "table.h" +#include "filter.h" +#include "igen.h" + +#include "ld-insn.h" +#include "ld-decode.h" + +#include "gen.h" + +#include "gen-semantics.h" +#include "gen-idecode.h" +#include "gen-icache.h" + + + +static void +print_icache_function_header (lf *file, + const char *basename, + const char *format_name, + opcode_bits *expanded_bits, + int is_function_definition, + int nr_prefetched_words) +{ + lf_printf (file, "\n"); + lf_print__function_type_function (file, print_icache_function_type, + "EXTERN_ICACHE", " "); + print_function_name (file, + basename, format_name, NULL, + expanded_bits, function_name_prefix_icache); + lf_printf (file, "\n("); + print_icache_function_formal (file, nr_prefetched_words); + lf_printf (file, ")"); + if (!is_function_definition) + lf_printf (file, ";"); + lf_printf (file, "\n"); +} + + +void +print_icache_declaration (lf *file, + insn_entry * insn, + opcode_bits *expanded_bits, + insn_opcodes *opcodes, int nr_prefetched_words) +{ + print_icache_function_header (file, + insn->name, + insn->format_name, + expanded_bits, + 0 /* is not function definition */ , + nr_prefetched_words); +} + + + +static void +print_icache_extraction (lf *file, + const char *format_name, + cache_entry_type cache_type, + const char *entry_name, + const char *entry_type, + const char *entry_expression, + char *single_insn_field, + line_ref *line, + insn_field_entry *cur_field, + opcode_bits *expanded_bits, + icache_decl_type what_to_declare, + icache_body_type what_to_do) +{ + const char *expression; + opcode_bits *bits; + char *reason; + ASSERT (format_name != NULL); + ASSERT (entry_name != NULL); + + /* figure out exactly what should be going on here */ + switch (cache_type) + { + case scratch_value: + if ((what_to_do & put_values_in_icache) + || what_to_do == do_not_use_icache) + { + reason = "scratch"; + what_to_do = do_not_use_icache; + } + else + return; + break; + case compute_value: + if ((what_to_do & get_values_from_icache) + || what_to_do == do_not_use_icache) + { + reason = "compute"; + what_to_do = do_not_use_icache; + } + else + return; + break; + case cache_value: + if ((what_to_declare != undef_variables) + || !(what_to_do & put_values_in_icache)) + { + reason = "cache"; + what_to_declare = ((what_to_do & put_values_in_icache) + ? declare_variables : what_to_declare); + } + else + return; + break; + default: + abort (); /* Bad switch. */ + } + + /* For the type, default to a simple unsigned */ + if (entry_type == NULL || strlen (entry_type) == 0) + entry_type = "unsigned"; + + /* look through the set of expanded sub fields to see if this field + has been given a constant value */ + for (bits = expanded_bits; bits != NULL; bits = bits->next) + { + if (bits->field == cur_field) + break; + } + + /* Define a storage area for the cache element */ + switch (what_to_declare) + { + case undef_variables: + /* We've finished with the #define value - destory it */ + lf_indent_suppress (file); + lf_printf (file, "#undef %s\n", entry_name); + return; + case define_variables: + /* Using direct access for this entry, clear any prior + definition, then define it */ + lf_indent_suppress (file); + lf_printf (file, "#undef %s\n", entry_name); + /* Don't type cast pointer types! */ + lf_indent_suppress (file); + if (strchr (entry_type, '*') != NULL) + lf_printf (file, "#define %s (", entry_name); + else + lf_printf (file, "#define %s ((%s) ", entry_name, entry_type); + break; + case declare_variables: + /* using variables to define the value */ + if (line != NULL) + lf_print__line_ref (file, line); + lf_printf (file, "%s const %s UNUSED = ", entry_type, entry_name); + break; + } + + + /* define a value for that storage area as determined by what is in + the cache */ + if (bits != NULL + && single_insn_field != NULL + && strcmp (entry_name, single_insn_field) == 0 + && strcmp (entry_name, cur_field->val_string) == 0 + && ((bits->opcode->is_boolean && bits->value == 0) + || (!bits->opcode->is_boolean))) + { + /* The cache rule is specifying what to do with a simple + instruction field. + + Because of instruction expansion, the field is either a + constant value or equal to the specified constant (boolean + comparison). (The latter indicated by bits->value == 0). + + The case of a field not being equal to the specified boolean + value is handled later. */ + expression = "constant field"; + ASSERT (bits->field == cur_field); + if (bits->opcode->is_boolean) + { + ASSERT (bits->value == 0); + lf_printf (file, "%d", bits->opcode->boolean_constant); + } + else if (bits->opcode->last < bits->field->last) + { + lf_printf (file, "%d", + bits->value << (bits->field->last - bits->opcode->last)); + } + else + { + lf_printf (file, "%d", bits->value); + } + } + else if (bits != NULL + && single_insn_field != NULL + && strncmp (entry_name, + single_insn_field, + strlen (single_insn_field)) == 0 + && strncmp (entry_name + strlen (single_insn_field), + "_is_", + strlen ("_is_")) == 0 + && ((bits->opcode->is_boolean + && ((unsigned) + atol (entry_name + strlen (single_insn_field) + + strlen ("_is_")) == bits->opcode->boolean_constant)) + || (!bits->opcode->is_boolean))) + { + /* The cache rule defines an entry for the comparison between a + single instruction field and a constant. The value of the + comparison in someway matches that of the opcode field that + was made constant through expansion. */ + expression = "constant compare"; + if (bits->opcode->is_boolean) + { + lf_printf (file, "%d /* %s == %d */", + bits->value == 0, + single_insn_field, bits->opcode->boolean_constant); + } + else if (bits->opcode->last < bits->field->last) + { + lf_printf (file, "%d /* %s == %d */", + (atol + (entry_name + strlen (single_insn_field) + + strlen ("_is_")) == + (bits-> + value << (bits->field->last - bits->opcode->last))), + single_insn_field, + (bits-> + value << (bits->field->last - bits->opcode->last))); + } + else + { + lf_printf (file, "%d /* %s == %d */", + (atol + (entry_name + strlen (single_insn_field) + + strlen ("_is_")) == bits->value), single_insn_field, + bits->value); + } + } + else + { + /* put the field in the local variable, possibly also enter it + into the cache */ + expression = "extraction"; + /* handle the cache */ + if ((what_to_do & get_values_from_icache) + || (what_to_do & put_values_in_icache)) + { + lf_printf (file, "cache_entry->crack.%s.%s", + format_name, entry_name); + if (what_to_do & put_values_in_icache) /* also put it in the cache? */ + { + lf_printf (file, " = "); + } + } + if ((what_to_do & put_values_in_icache) + || what_to_do == do_not_use_icache) + { + if (cur_field != NULL) + { + if (entry_expression != NULL && strlen (entry_expression) > 0) + error (line, + "Instruction field entry with nonempty expression\n"); + if (cur_field->first == 0 + && cur_field->last == options.insn_bit_size - 1) + lf_printf (file, "(instruction_%d)", cur_field->word_nr); + else if (cur_field->last == options.insn_bit_size - 1) + lf_printf (file, "MASKED%d (instruction_%d, %d, %d)", + options.insn_bit_size, + cur_field->word_nr, + i2target (options.hi_bit_nr, cur_field->first), + i2target (options.hi_bit_nr, cur_field->last)); + else + lf_printf (file, "EXTRACTED%d (instruction_%d, %d, %d)", + options.insn_bit_size, + cur_field->word_nr, + i2target (options.hi_bit_nr, cur_field->first), + i2target (options.hi_bit_nr, cur_field->last)); + } + else + { + lf_printf (file, "%s", entry_expression); + } + } + } + + switch (what_to_declare) + { + case define_variables: + lf_printf (file, ")"); + break; + case undef_variables: + break; + case declare_variables: + lf_printf (file, ";"); + break; + } + + ASSERT (reason != NULL && expression != NULL); + lf_printf (file, " /* %s - %s */\n", reason, expression); +} + + +void +print_icache_body (lf *file, + insn_entry * instruction, + opcode_bits *expanded_bits, + cache_entry *cache_rules, + icache_decl_type what_to_declare, + icache_body_type what_to_do, int nr_prefetched_words) +{ + /* extract instruction fields */ + lf_printf (file, "/* Extraction: %s\n", instruction->name); + lf_printf (file, " "); + switch (what_to_declare) + { + case define_variables: + lf_printf (file, "#define"); + break; + case declare_variables: + lf_printf (file, "declare"); + break; + case undef_variables: + lf_printf (file, "#undef"); + break; + } + lf_printf (file, " "); + switch (what_to_do) + { + case get_values_from_icache: + lf_printf (file, "get-values-from-icache"); + break; + case put_values_in_icache: + lf_printf (file, "put-values-in-icache"); + break; + case both_values_and_icache: + lf_printf (file, "get-values-from-icache|put-values-in-icache"); + break; + case do_not_use_icache: + lf_printf (file, "do-not-use-icache"); + break; + } + lf_printf (file, "\n "); + print_insn_words (file, instruction); + lf_printf (file, " */\n"); + + /* pass zero - fetch from memory any missing instructions. + + Some of the instructions will have already been fetched (in the + instruction array), others will still need fetching. */ + switch (what_to_do) + { + case get_values_from_icache: + break; + case put_values_in_icache: + case both_values_and_icache: + case do_not_use_icache: + { + int word_nr; + switch (what_to_declare) + { + case undef_variables: + break; + case define_variables: + case declare_variables: + for (word_nr = nr_prefetched_words; + word_nr < instruction->nr_words; word_nr++) + { + /* FIXME - should be using print_icache_extraction? */ + lf_printf (file, + "%sinstruction_word instruction_%d UNUSED = ", + options.module.global.prefix.l, word_nr); + lf_printf (file, "IMEM%d_IMMED (cia, %d)", + options.insn_bit_size, word_nr); + lf_printf (file, ";\n"); + } + } + } + } + + /* if putting the instruction words in the cache, define references + for them */ + if (options.gen.insn_in_icache) + { + /* FIXME: is the instruction_word type correct? */ + print_icache_extraction (file, instruction->format_name, cache_value, "insn", /* name */ + "instruction_word", /* type */ + "instruction", /* expression */ + NULL, /* origin */ + NULL, /* line */ + NULL, NULL, what_to_declare, what_to_do); + } + lf_printf (file, "\n"); + + /* pass one - process instruction fields. + + If there is no cache rule, the default is to enter the field into + the cache */ + { + insn_word_entry *word; + for (word = instruction->words; word != NULL; word = word->next) + { + insn_field_entry *cur_field; + for (cur_field = word->first; + cur_field->first < options.insn_bit_size; + cur_field = cur_field->next) + { + if (cur_field->type == insn_field_string) + { + cache_entry *cache_rule; + cache_entry_type value_type = cache_value; + line_ref *value_line = instruction->line; + /* check the cache table to see if it contains a rule + overriding the default cache action for an + instruction field */ + for (cache_rule = cache_rules; + cache_rule != NULL; cache_rule = cache_rule->next) + { + if (filter_is_subset (instruction->field_names, + cache_rule->original_fields) + && strcmp (cache_rule->name, + cur_field->val_string) == 0) + { + value_type = cache_rule->entry_type; + value_line = cache_rule->line; + if (value_type == compute_value) + { + options.warning (cache_rule->line, + "instruction field of type `compute' changed to `cache'\n"); + cache_rule->entry_type = cache_value; + } + break; + } + } + /* Define an entry for the field within the + instruction */ + print_icache_extraction (file, instruction->format_name, value_type, cur_field->val_string, /* name */ + NULL, /* type */ + NULL, /* expression */ + cur_field->val_string, /* insn field */ + value_line, + cur_field, + expanded_bits, + what_to_declare, what_to_do); + } + } + } + } + + /* pass two - any cache fields not processed above */ + { + cache_entry *cache_rule; + for (cache_rule = cache_rules; + cache_rule != NULL; cache_rule = cache_rule->next) + { + if (filter_is_subset (instruction->field_names, + cache_rule->original_fields) + && !filter_is_member (instruction->field_names, cache_rule->name)) + { + char *single_field = + filter_next (cache_rule->original_fields, ""); + if (filter_next (cache_rule->original_fields, single_field) != + NULL) + single_field = NULL; + print_icache_extraction (file, instruction->format_name, cache_rule->entry_type, cache_rule->name, cache_rule->type, cache_rule->expression, single_field, cache_rule->line, NULL, /* cur_field */ + expanded_bits, + what_to_declare, what_to_do); + } + } + } + + lf_print__internal_ref (file); +} + + + +typedef struct _form_fields form_fields; +struct _form_fields +{ + char *name; + filter *fields; + form_fields *next; +}; + +static form_fields * +insn_table_cache_fields (insn_table *isa) +{ + form_fields *forms = NULL; + insn_entry *insn; + for (insn = isa->insns; insn != NULL; insn = insn->next) + { + form_fields **form = &forms; + while (1) + { + if (*form == NULL) + { + /* new format name, add it */ + form_fields *new_form = ZALLOC (form_fields); + new_form->name = insn->format_name; + filter_add (&new_form->fields, insn->field_names); + *form = new_form; + break; + } + else if (strcmp ((*form)->name, insn->format_name) == 0) + { + /* already present, add field names to the existing list */ + filter_add (&(*form)->fields, insn->field_names); + break; + } + form = &(*form)->next; + } + } + return forms; +} + + + +extern void +print_icache_struct (lf *file, insn_table *isa, cache_entry *cache_rules) +{ + /* Create a list of all the different instruction formats with their + corresponding field names. */ + form_fields *formats = insn_table_cache_fields (isa); + + lf_printf (file, "\n"); + lf_printf (file, "#define WITH_%sIDECODE_CACHE_SIZE %d\n", + options.module.global.prefix.u, + (options.gen.icache ? options.gen.icache_size : 0)); + lf_printf (file, "\n"); + + /* create an instruction cache if being used */ + if (options.gen.icache) + { + lf_printf (file, "typedef struct _%sidecode_cache {\n", + options.module.global.prefix.l); + lf_indent (file, +2); + { + form_fields *format; + lf_printf (file, "unsigned_word address;\n"); + lf_printf (file, "void *semantic;\n"); + lf_printf (file, "union {\n"); + lf_indent (file, +2); + for (format = formats; format != NULL; format = format->next) + { + lf_printf (file, "struct {\n"); + lf_indent (file, +2); + { + cache_entry *cache_rule; + char *field; + /* space for any instruction words */ + if (options.gen.insn_in_icache) + lf_printf (file, "instruction_word insn[%d];\n", + isa->max_nr_words); + /* define an entry for any applicable cache rules */ + for (cache_rule = cache_rules; + cache_rule != NULL; cache_rule = cache_rule->next) + { + /* nb - sort of correct - should really check against + individual instructions */ + if (filter_is_subset + (format->fields, cache_rule->original_fields)) + { + char *memb; + lf_printf (file, "%s %s;", + (cache_rule->type == NULL + ? "unsigned" + : cache_rule->type), cache_rule->name); + lf_printf (file, " /*"); + for (memb = + filter_next (cache_rule->original_fields, ""); + memb != NULL; + memb = + filter_next (cache_rule->original_fields, memb)) + { + lf_printf (file, " %s", memb); + } + lf_printf (file, " */\n"); + } + } + /* define an entry for any fields not covered by a cache rule */ + for (field = filter_next (format->fields, ""); + field != NULL; field = filter_next (format->fields, field)) + { + cache_entry *cache_rule; + int found_rule = 0; + for (cache_rule = cache_rules; + cache_rule != NULL; cache_rule = cache_rule->next) + { + if (strcmp (cache_rule->name, field) == 0) + { + found_rule = 1; + break; + } + } + if (!found_rule) + lf_printf (file, "unsigned %s; /* default */\n", field); + } + } + lf_indent (file, -2); + lf_printf (file, "} %s;\n", format->name); + } + lf_indent (file, -2); + lf_printf (file, "} crack;\n"); + } + lf_indent (file, -2); + lf_printf (file, "} %sidecode_cache;\n", + options.module.global.prefix.l); + } + else + { + /* alernativly, since no cache, emit a dummy definition for + idecode_cache so that code refering to the type can still compile */ + lf_printf (file, "typedef void %sidecode_cache;\n", + options.module.global.prefix.l); + } + lf_printf (file, "\n"); +} + + + +static void +print_icache_function (lf *file, + insn_entry * instruction, + opcode_bits *expanded_bits, + insn_opcodes *opcodes, + cache_entry *cache_rules, int nr_prefetched_words) +{ + int indent; + + /* generate code to enter decoded instruction into the icache */ + lf_printf (file, "\n"); + lf_print__function_type_function (file, print_icache_function_type, + "EXTERN_ICACHE", "\n"); + indent = print_function_name (file, + instruction->name, + instruction->format_name, + NULL, + expanded_bits, function_name_prefix_icache); + indent += lf_printf (file, " "); + lf_indent (file, +indent); + lf_printf (file, "("); + print_icache_function_formal (file, nr_prefetched_words); + lf_printf (file, ")\n"); + lf_indent (file, -indent); + + /* function header */ + lf_printf (file, "{\n"); + lf_indent (file, +2); + + print_my_defines (file, + instruction->name, + instruction->format_name, expanded_bits); + print_itrace (file, instruction, 1 /*putting-value-in-cache */ ); + + print_idecode_validate (file, instruction, opcodes); + + lf_printf (file, "\n"); + lf_printf (file, "{\n"); + lf_indent (file, +2); + if (options.gen.semantic_icache) + lf_printf (file, "unsigned_word nia;\n"); + print_icache_body (file, + instruction, + expanded_bits, + cache_rules, + (options.gen.direct_access + ? define_variables + : declare_variables), + (options.gen.semantic_icache + ? both_values_and_icache + : put_values_in_icache), nr_prefetched_words); + + lf_printf (file, "\n"); + lf_printf (file, "cache_entry->address = cia;\n"); + lf_printf (file, "cache_entry->semantic = "); + print_function_name (file, + instruction->name, + instruction->format_name, + NULL, expanded_bits, function_name_prefix_semantics); + lf_printf (file, ";\n"); + lf_printf (file, "\n"); + + if (options.gen.semantic_icache) + { + lf_printf (file, "/* semantic routine */\n"); + print_semantic_body (file, instruction, expanded_bits, opcodes); + lf_printf (file, "return nia;\n"); + } + + if (!options.gen.semantic_icache) + { + lf_printf (file, "/* return the function proper */\n"); + lf_printf (file, "return "); + print_function_name (file, + instruction->name, + instruction->format_name, + NULL, + expanded_bits, function_name_prefix_semantics); + lf_printf (file, ";\n"); + } + + if (options.gen.direct_access) + { + print_icache_body (file, + instruction, + expanded_bits, + cache_rules, + undef_variables, + (options.gen.semantic_icache + ? both_values_and_icache + : put_values_in_icache), nr_prefetched_words); + } + + lf_indent (file, -2); + lf_printf (file, "}\n"); + lf_indent (file, -2); + lf_printf (file, "}\n"); +} + + +void +print_icache_definition (lf *file, + insn_entry * insn, + opcode_bits *expanded_bits, + insn_opcodes *opcodes, + cache_entry *cache_rules, int nr_prefetched_words) +{ + print_icache_function (file, + insn, + expanded_bits, + opcodes, cache_rules, nr_prefetched_words); +} + + + +void +print_icache_internal_function_declaration (lf *file, + function_entry * function, + void *data) +{ + ASSERT (options.gen.icache); + if (function->is_internal) + { + lf_printf (file, "\n"); + lf_print__function_type_function (file, print_icache_function_type, + "INLINE_ICACHE", "\n"); + print_function_name (file, + function->name, + NULL, NULL, NULL, function_name_prefix_icache); + lf_printf (file, "\n("); + print_icache_function_formal (file, 0); + lf_printf (file, ");\n"); + } +} + + +void +print_icache_internal_function_definition (lf *file, + function_entry * function, + void *data) +{ + ASSERT (options.gen.icache); + if (function->is_internal) + { + lf_printf (file, "\n"); + lf_print__function_type_function (file, print_icache_function_type, + "INLINE_ICACHE", "\n"); + print_function_name (file, + function->name, + NULL, NULL, NULL, function_name_prefix_icache); + lf_printf (file, "\n("); + print_icache_function_formal (file, 0); + lf_printf (file, ")\n"); + lf_printf (file, "{\n"); + lf_indent (file, +2); + lf_printf (file, "/* semantic routine */\n"); + if (options.gen.semantic_icache) + { + lf_print__line_ref (file, function->code->line); + table_print_code (file, function->code); + lf_printf (file, + "error (\"Internal function must longjump\\n\");\n"); + lf_printf (file, "return 0;\n"); + } + else + { + lf_printf (file, "return "); + print_function_name (file, + function->name, + NULL, + NULL, NULL, function_name_prefix_semantics); + lf_printf (file, ";\n"); + } + + lf_print__internal_ref (file); + lf_indent (file, -2); + lf_printf (file, "}\n"); + } +}
gen-icache.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen-support.c =================================================================== --- gen-support.c (nonexistent) +++ gen-support.c (revision 841) @@ -0,0 +1,213 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +#include "misc.h" +#include "lf.h" +#include "table.h" +#include "filter.h" + +#include "igen.h" + +#include "ld-insn.h" +#include "ld-decode.h" + +#include "gen.h" + +#include "gen-semantics.h" +#include "gen-support.h" + +static void +print_support_function_name (lf *file, + function_entry * function, + int is_function_definition) +{ + if (function->is_internal) + { + lf_print__function_type_function (file, print_semantic_function_type, + "INLINE_SUPPORT", + (is_function_definition ? "\n" : + " ")); + print_function_name (file, function->name, NULL, NULL, NULL, + function_name_prefix_semantics); + lf_printf (file, "\n("); + lf_indent (file, +1); + print_semantic_function_formal (file, 0); + lf_indent (file, -1); + lf_printf (file, ")"); + if (!is_function_definition) + lf_printf (file, ";"); + lf_printf (file, "\n"); + } + else + { + /* map the name onto a globally valid name */ + if (!is_function_definition + && strcmp (options.module.support.prefix.l, "") != 0) + { + lf_indent_suppress (file); + lf_printf (file, "#define %s %s%s\n", + function->name, + options.module.support.prefix.l, function->name); + } + lf_print__function_type (file, + function->type, + "INLINE_SUPPORT", + (is_function_definition ? "\n" : " ")); + lf_printf (file, "%s%s\n(", + options.module.support.prefix.l, function->name); + if (options.gen.smp) + lf_printf (file, + "sim_cpu *cpu, %sinstruction_address cia, int MY_INDEX", + options.module.support.prefix.l); + else + lf_printf (file, + "SIM_DESC sd, %sinstruction_address cia, int MY_INDEX", + options.module.support.prefix.l); + if (function->param != NULL && strlen (function->param) > 0) + lf_printf (file, ", %s", function->param); + lf_printf (file, ")%s", (is_function_definition ? "\n" : ";\n")); + } +} + + +static void +support_h_function (lf *file, function_entry * function, void *data) +{ + ASSERT (function->type != NULL); + print_support_function_name (file, function, 0 /*!is_definition */ ); + lf_printf (file, "\n"); +} + + +extern void +gen_support_h (lf *file, insn_table *table) +{ + /* output the definition of `SD_' */ + if (options.gen.smp) + { + lf_printf (file, "#define SD CPU_STATE (cpu)\n"); + lf_printf (file, "#define CPU cpu\n"); + lf_printf (file, "#define CPU_ cpu\n"); + } + else + { + lf_printf (file, "#define SD sd\n"); + lf_printf (file, "#define CPU (STATE_CPU (sd, 0))\n"); + lf_printf (file, "#define CPU_ sd\n"); + } + + lf_printf (file, "#define CIA_ cia\n"); + if (options.gen.delayed_branch) + { + lf_printf (file, "#define CIA cia.ip\n"); + lf_printf (file, + "/* #define NIA nia.dp -- do not define, ambigious */\n"); + } + else + { + lf_printf (file, "#define CIA cia\n"); + lf_printf (file, "#define NIA nia\n"); + } + lf_printf (file, "\n"); + + lf_printf (file, "#define SD_ CPU_, CIA_, MY_INDEX\n"); + lf_printf (file, "#define _SD SD_ /* deprecated */\n"); + lf_printf (file, "\n"); + + /* Map _xxxx onto the shorter xxxx for the following names: + + instruction_word + idecode_issue + semantic_illegal + + Map defined here as name space problems are created when the name is + defined in idecode.h */ + if (strcmp (options.module.idecode.prefix.l, "") != 0) + { + lf_indent_suppress (file); + lf_printf (file, "#define %s %s%s\n", + "instruction_word", + options.module.idecode.prefix.l, "instruction_word"); + lf_printf (file, "\n"); + lf_indent_suppress (file); + lf_printf (file, "#define %s %s%s\n", + "idecode_issue", + options.module.idecode.prefix.l, "idecode_issue"); + lf_printf (file, "\n"); + lf_indent_suppress (file); + lf_printf (file, "#define %s %s%s\n", + "semantic_illegal", + options.module.idecode.prefix.l, "semantic_illegal"); + lf_printf (file, "\n"); + } + + /* output a declaration for all functions */ + function_entry_traverse (file, table->functions, support_h_function, NULL); + lf_printf (file, "\n"); + lf_printf (file, "#if defined(SUPPORT_INLINE)\n"); + lf_printf (file, "# if ((SUPPORT_INLINE & INCLUDE_MODULE)\\\n"); + lf_printf (file, " && (SUPPORT_INLINE & INCLUDED_BY_MODULE))\n"); + lf_printf (file, "# include \"%ssupport.c\"\n", + options.module.support.prefix.l); + lf_printf (file, "# endif\n"); + lf_printf (file, "#endif\n"); +} + +static void +support_c_function (lf *file, function_entry * function, void *data) +{ + ASSERT (function->type != NULL); + print_support_function_name (file, function, 1 /*!is_definition */ ); + lf_printf (file, "{\n"); + lf_indent (file, +2); + if (function->code == NULL) + error (function->line, "Function without body (or null statement)"); + lf_print__line_ref (file, function->code->line); + table_print_code (file, function->code); + if (function->is_internal) + { + lf_printf (file, + "sim_engine_abort (SD, CPU, cia, \"Internal function must longjump\\n\");\n"); + lf_printf (file, "return cia;\n"); + } + lf_indent (file, -2); + lf_printf (file, "}\n"); + lf_print__internal_ref (file); + lf_printf (file, "\n"); +} + + +void +gen_support_c (lf *file, insn_table *table) +{ + lf_printf (file, "#include \"sim-main.h\"\n"); + lf_printf (file, "#include \"%sidecode.h\"\n", + options.module.idecode.prefix.l); + lf_printf (file, "#include \"%sitable.h\"\n", + options.module.itable.prefix.l); + lf_printf (file, "#include \"%ssupport.h\"\n", + options.module.support.prefix.l); + lf_printf (file, "\n"); + + /* output a definition (c-code) for all functions */ + function_entry_traverse (file, table->functions, support_c_function, NULL); +}
gen-support.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: filter.c =================================================================== --- filter.c (nonexistent) +++ filter.c (revision 841) @@ -0,0 +1,353 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +#include + +#include "config.h" + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + +#include "misc.h" +#include "lf.h" +#include "filter.h" + +struct _filter +{ + char *member; + filter *next; +}; + + +void +filter_parse (filter **filters, const char *filt) +{ + while (strlen (filt) > 0) + { + filter *new_filter; + filter **last; + /* break out a member of the filter list */ + const char *flag = filt; + unsigned /*size_t */ len; + filt = strchr (filt, ','); + if (filt == NULL) + { + filt = strchr (flag, '\0'); + len = strlen (flag); + } + else + { + len = filt - flag; + filt = filt + 1; + } + /* find an insertion point - sorted order */ + last = filters; + while (*last != NULL && strncmp (flag, (*last)->member, len) > 0) + last = &(*last)->next; + if (*last != NULL + && strncmp (flag, (*last)->member, len) == 0 + && strlen ((*last)->member) == len) + continue; /* duplicate */ + /* create an entry for that member */ + new_filter = ZALLOC (filter); + new_filter->member = NZALLOC (char, len + 1); + strncpy (new_filter->member, flag, len); + /* insert it */ + new_filter->next = *last; + *last = new_filter; + } +} + + +void +filter_add (filter **set, filter *add) +{ + while (add != NULL) + { + int cmp; + if (*set == NULL) + cmp = 1; /* set->member > add->member */ + else + cmp = strcmp ((*set)->member, add->member); + if (cmp > 0) + { + /* insert it here */ + filter *new = ZALLOC (filter); + new->member = NZALLOC (char, strlen (add->member) + 1); + strcpy (new->member, add->member); + new->next = *set; + *set = new; + add = add->next; + } + else if (cmp == 0) + { + /* already in set */ + add = add->next; + } + else /* cmp < 0 */ + { + /* not reached insertion point */ + set = &(*set)->next; + } + } +} + + +int +filter_is_subset (filter *superset, filter *subset) +{ + while (1) + { + int cmp; + if (subset == NULL) + return 1; + if (superset == NULL) + return 0; /* subset isn't finished */ + cmp = strcmp (subset->member, superset->member); + if (cmp < 0) + return 0; /* not found */ + else if (cmp == 0) + subset = subset->next; /* found */ + else if (cmp > 0) + superset = superset->next; /* later in list? */ + } +} + + +int +filter_is_common (filter *l, filter *r) +{ + while (1) + { + int cmp; + if (l == NULL) + return 0; + if (r == NULL) + return 0; + cmp = strcmp (l->member, r->member); + if (cmp < 0) + l = l->next; + else if (cmp == 0) + return 1; /* common member */ + else if (cmp > 0) + r = r->next; + } +} + + +int +filter_is_member (filter *filt, const char *flag) +{ + int index = 1; + while (filt != NULL) + { + if (strcmp (flag, filt->member) == 0) + return index; + filt = filt->next; + index++; + } + return 0; +} + + +int +is_filtered_out (filter *filters, const char *flags) +{ + while (strlen (flags) > 0) + { + int present; + filter *filt = filters; + /* break the string up */ + char *end = strchr (flags, ','); + char *next; + unsigned /*size_t */ len; + if (end == NULL) + { + end = strchr (flags, '\0'); + next = end; + } + else + { + next = end + 1; + } + len = end - flags; + /* check that it is present */ + present = 0; + filt = filters; + while (filt != NULL) + { + if (strncmp (flags, filt->member, len) == 0 + && strlen (filt->member) == len) + { + present = 1; + break; + } + filt = filt->next; + } + if (!present) + return 1; + flags = next; + } + return 0; +} + + +#if 0 +int +it_is (const char *flag, const char *flags) +{ + int flag_len = strlen (flag); + while (*flags != '\0') + { + if (!strncmp (flags, flag, flag_len) + && (flags[flag_len] == ',' || flags[flag_len] == '\0')) + return 1; + while (*flags != ',') + { + if (*flags == '\0') + return 0; + flags++; + } + flags++; + } + return 0; +} +#endif + + +char * +filter_next (filter *set, char *member) +{ + while (set != NULL) + { + if (strcmp (set->member, member) > 0) + return set->member; + set = set->next; + } + return NULL; +} + + +void +dump_filter (lf *file, char *prefix, filter *set, char *suffix) +{ + char *member; + lf_printf (file, "%s", prefix); + member = filter_next (set, ""); + if (member != NULL) + { + while (1) + { + lf_printf (file, "%s", member); + member = filter_next (set, member); + if (member == NULL) + break; + lf_printf (file, ","); + } + } + lf_printf (file, "%s", suffix); +} + + +#ifdef MAIN +int +main (int argc, char **argv) +{ + filter *subset = NULL; + filter *superset = NULL; + lf *l; + int i; + if (argc < 2) + { + printf ("Usage: filter ...\n"); + exit (1); + } + + /* load the filter up */ + filter_parse (&subset, argv[1]); + for (i = 2; i < argc; i++) + filter_parse (&superset, argv[i]); + + /* dump various info */ + l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-filter"); +#if 0 + if (is_filtered_out (argv[1], superset)) + lf_printf (l, "excluded\n"); + else + lf_printf (l, "included\n"); +#endif + /* subset */ + { + dump_filter (l, "{", subset, " }"); + if (filter_is_subset (superset, subset)) + lf_printf (l, " subset of "); + else + lf_printf (l, " !subset of "); + dump_filter (l, "{", superset, " }"); + lf_printf (l, "\n"); + } + /* intersection */ + { + dump_filter (l, "{", subset, " }"); + if (filter_is_common (subset, superset)) + lf_printf (l, " intersects "); + else + lf_printf (l, " !intersects "); + dump_filter (l, "{", superset, " }"); + lf_printf (l, "\n"); + } + /* membership */ + { + filter *memb = subset; + while (memb != NULL) + { + lf_printf (l, "%s", memb->member); + if (filter_is_member (superset, memb->member)) + lf_printf (l, " in "); + else + lf_printf (l, " !in "); + dump_filter (l, "{", superset, " }"); + lf_printf (l, "\n"); + memb = memb->next; + } + } + /* addition */ + { + filter *add = NULL; + filter_add (&add, superset); + filter_add (&add, subset); + dump_filter (l, "{", add, " }"); + lf_printf (l, " = "); + dump_filter (l, "{", subset, " }"); + lf_printf (l, " + "); + dump_filter (l, "{", superset, " }"); + lf_printf (l, "\n"); + } + + return 0; +} +#endif
filter.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: igen.h =================================================================== --- igen.h (nonexistent) +++ igen.h (revision 841) @@ -0,0 +1,251 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +/* code-generation options: */ + +typedef enum +{ + + /* Transfer control to an instructions semantic code using the the + standard call/return mechanism */ + + generate_calls, + + /* Transfer control to an instructions semantic code using + (computed) goto's instead of the more conventional call/return + mechanism */ + + generate_jumps, + +} +igen_code; + +typedef enum +{ + nia_is_cia_plus_one, + nia_is_void, + nia_is_invalid, +} +igen_nia; + + + +typedef struct _igen_gen_options igen_gen_options; +struct _igen_gen_options +{ + int direct_access; + int semantic_icache; + int insn_in_icache; + int conditional_issue; + int slot_verification; + int delayed_branch; + + /* If zeroing a register, which one? */ + int zero_reg; + int zero_reg_nr; + + /* should multiple simulators be generated? */ + int multi_sim; + + /* name of the default multi-sim model */ + char *default_model; + + /* should the simulator support multi word instructions and if so, + what is the max nr of words. */ + int multi_word; + + /* SMP? Should the generated code include SMP support (>0) and if + so, for how many processors? */ + int smp; + + /* how should the next instruction address be computed? */ + igen_nia nia; + + /* nr of instructions in the decoded instruction cache */ + int icache; + int icache_size; + + /* see above */ + igen_code code; +}; + + +typedef struct _igen_trace_options igen_trace_options; +struct _igen_trace_options +{ + int rule_selection; + int rule_rejection; + int insn_insertion; + int insn_expansion; + int entries; + int combine; +}; + +typedef struct _igen_name +{ + char *u; + char *l; +} +igen_name; +typedef struct _igen_module +{ + igen_name prefix; + igen_name suffix; +} +igen_module; + +typedef struct _igen_module_options +{ + igen_module global; + igen_module engine; + igen_module icache; + igen_module idecode; + igen_module itable; + igen_module semantics; + igen_module support; +} +igen_module_options; + +typedef struct _igen_decode_options igen_decode_options; +struct _igen_decode_options +{ + + /* Combine tables? Should the generator make a second pass through + each generated table looking for any sub-entries that contain the + same instructions. Those entries being merged into a single + table */ + int combine; + + /* Instruction expansion? Should the semantic code for each + instruction, when the oportunity arrises, be expanded according + to the variable opcode files that the instruction decode process + renders constant */ + int duplicate; + + /* Treat reserved fields as constant (zero) instead of ignoring + their value when determining decode tables */ + int zero_reserved; + + /* Convert any padded switch rules into goto_switch */ + int switch_as_goto; + + /* Force all tables to be generated with this lookup mechanism */ + char *overriding_gen; +}; + + +typedef struct _igen_warn_options igen_warn_options; +struct _igen_warn_options +{ + + /* Issue warning about discarded instructions */ + int discard; + + /* Issue warning about invalid instruction widths */ + int width; + + /* Issue warning about unimplemented instructions */ + int unimplemented; + +}; + + + +typedef struct _igen_options igen_options; +struct _igen_options +{ + + /* What does the instruction look like - bit ordering, size, widths or + offesets */ + int hi_bit_nr; + int insn_bit_size; + int insn_specifying_widths; + + /* what should global names be prefixed with? */ + igen_module_options module; + + /* See above for options and flags */ + igen_gen_options gen; + + /* See above for trace options */ + igen_trace_options trace; + + /* See above for include options */ + table_include *include; + + /* See above for decode options */ + igen_decode_options decode; + + /* Filter set to be used on the flag field of the instruction table */ + filter *flags_filter; + + /* See above for warn options */ + igen_warn_options warn; + + /* Be more picky about the input */ + error_func (*warning); + + /* Model (processor) set - like flags_filter. Used to select the + specific ISA within a processor family. */ + filter *model_filter; + + /* Format name set */ + filter *format_name_filter; +}; + +extern igen_options options; + +/* default options - hopefully backward compatible */ +#define INIT_OPTIONS() \ +do { \ + memset (&options, 0, sizeof options); \ + memset (&options.warn, -1, sizeof (options.warn)); \ + options.hi_bit_nr = 0; \ + options.insn_bit_size = default_insn_bit_size; \ + options.insn_specifying_widths = 0; \ + options.module.global.prefix.u = ""; \ + options.module.global.prefix.l = ""; \ + /* the prefixes */ \ + options.module.engine = options.module.global; \ + options.module.icache = options.module.global; \ + options.module.idecode = options.module.global; \ + options.module.itable = options.module.global; \ + options.module.semantics = options.module.global; \ + options.module.support = options.module.global; \ + /* the suffixes */ \ + options.module.engine.suffix.l = "engine"; \ + options.module.engine.suffix.u = "ENGINE"; \ + options.module.icache.suffix.l = "icache"; \ + options.module.icache.suffix.u = "ICACHE"; \ + options.module.idecode.suffix.l = "idecode"; \ + options.module.idecode.suffix.u = "IDECODE"; \ + options.module.itable.suffix.l = "itable"; \ + options.module.itable.suffix.u = "ITABLE"; \ + options.module.semantics.suffix.l = "semantics"; \ + options.module.semantics.suffix.u = "SEMANTICS"; \ + options.module.support.suffix.l = "support"; \ + options.module.support.suffix.u = "SUPPORT"; \ + /* misc stuff */ \ + options.gen.code = generate_calls; \ + options.gen.icache_size = 1024; \ + options.warning = warning; \ +} while (0)
igen.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: filter_host.h =================================================================== --- filter_host.h (nonexistent) +++ filter_host.h (revision 841) @@ -0,0 +1,27 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + +#ifndef _FILTER_HOST_H +#define _FILTER_HOST_H + +/* Remove directory part from filename */ +extern const char *filter_filename (const char *filename); +#endif
filter_host.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: table.c =================================================================== --- table.c (nonexistent) +++ table.c (revision 841) @@ -0,0 +1,621 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + + +#include +#include +#include +#include +#include + +#include "config.h" +#include "misc.h" +#include "lf.h" +#include "table.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +typedef struct _open_table open_table; +struct _open_table +{ + size_t size; + char *buffer; + char *pos; + line_ref pseudo_line; + line_ref real_line; + open_table *parent; + table *root; +}; +struct _table +{ + open_table *current; +}; + + +static line_ref * +current_line (open_table * file) +{ + line_ref *entry = ZALLOC (line_ref); + *entry = file->pseudo_line; + return entry; +} + +static table_entry * +new_table_entry (open_table * file, table_entry_type type) +{ + table_entry *entry; + entry = ZALLOC (table_entry); + entry->file = file->root; + entry->line = current_line (file); + entry->type = type; + return entry; +} + +static void +set_nr_table_entry_fields (table_entry *entry, int nr_fields) +{ + entry->field = NZALLOC (char *, nr_fields + 1); + entry->nr_fields = nr_fields; +} + + +void +table_push (table *root, + line_ref *line, table_include *includes, const char *file_name) +{ + FILE *ff; + open_table *file; + table_include dummy; + table_include *include = &dummy; + + /* dummy up a search of this directory */ + dummy.next = includes; + dummy.dir = ""; + + /* create a file descriptor */ + file = ZALLOC (open_table); + if (file == NULL) + { + perror (file_name); + exit (1); + } + file->root = root; + file->parent = root->current; + root->current = file; + + while (1) + { + /* save the file name */ + char *dup_name = + NZALLOC (char, strlen (include->dir) + strlen (file_name) + 2); + if (dup_name == NULL) + { + perror (file_name); + exit (1); + } + if (include->dir[0] != '\0') + { + strcat (dup_name, include->dir); + strcat (dup_name, "/"); + } + strcat (dup_name, file_name); + file->real_line.file_name = dup_name; + file->pseudo_line.file_name = dup_name; + /* open the file */ + + ff = fopen (dup_name, "rb"); + if (ff) + break; + /* zfree (dup_name); */ + if (include->next == NULL) + { + if (line != NULL) + error (line, "Problem opening file `%s'\n", file_name); + perror (file_name); + exit (1); + } + include = include->next; + } + + + /* determine the size */ + fseek (ff, 0, SEEK_END); + file->size = ftell (ff); + fseek (ff, 0, SEEK_SET); + + /* allocate this much memory */ + file->buffer = (char *) zalloc (file->size + 1); + if (file->buffer == NULL) + { + perror (file_name); + exit (1); + } + file->pos = file->buffer; + + /* read it all in */ + if (fread (file->buffer, 1, file->size, ff) < file->size) + { + perror (file_name); + exit (1); + } + file->buffer[file->size] = '\0'; + + /* set the initial line numbering */ + file->real_line.line_nr = 1; /* specifies current line */ + file->pseudo_line.line_nr = 1; /* specifies current line */ + + /* done */ + fclose (ff); +} + +table * +table_open (const char *file_name) +{ + table *root; + + /* create a file descriptor */ + root = ZALLOC (table); + if (root == NULL) + { + perror (file_name); + exit (1); + } + + table_push (root, NULL, NULL, file_name); + return root; +} + +char * +skip_spaces (char *chp) +{ + while (1) + { + if (*chp == '\0' || *chp == '\n' || !isspace (*chp)) + return chp; + chp++; + } +} + + +char * +back_spaces (char *start, char *chp) +{ + while (1) + { + if (chp <= start || !isspace (chp[-1])) + return chp; + chp--; + } +} + +char * +skip_digits (char *chp) +{ + while (1) + { + if (*chp == '\0' || *chp == '\n' || !isdigit (*chp)) + return chp; + chp++; + } +} + +char * +skip_to_separator (char *chp, char *separators) +{ + while (1) + { + char *sep = separators; + while (1) + { + if (*chp == *sep) + return chp; + if (*sep == '\0') + break; + sep++; + } + chp++; + } +} + +static char * +skip_to_null (char *chp) +{ + return skip_to_separator (chp, ""); +} + + +static char * +skip_to_nl (char *chp) +{ + return skip_to_separator (chp, "\n"); +} + + +static void +next_line (open_table * file) +{ + file->pos = skip_to_nl (file->pos); + if (*file->pos == '0') + error (&file->pseudo_line, "Missing at end of line\n"); + *file->pos = '\0'; + file->pos += 1; + file->real_line.line_nr += 1; + file->pseudo_line.line_nr += 1; +} + + +extern table_entry * +table_read (table *root) +{ + open_table *file = root->current; + table_entry *entry = NULL; + while (1) + { + + /* end-of-file? */ + while (*file->pos == '\0') + { + if (file->parent != NULL) + { + file = file->parent; + root->current = file; + } + else + return NULL; + } + + /* code_block? */ + if (*file->pos == '{') + { + char *chp; + next_line (file); /* discard leading brace */ + entry = new_table_entry (file, table_code_entry); + chp = file->pos; + /* determine how many lines are involved - look for "}" */ + { + int nr_lines = 0; + while (*file->pos != '}') + { + next_line (file); + nr_lines++; + } + set_nr_table_entry_fields (entry, nr_lines); + } + /* now enter each line */ + { + int line_nr; + for (line_nr = 0; line_nr < entry->nr_fields; line_nr++) + { + if (strncmp (chp, " ", 2) == 0) + entry->field[line_nr] = chp + 2; + else + entry->field[line_nr] = chp; + chp = skip_to_null (chp) + 1; + } + /* skip trailing brace */ + ASSERT (*file->pos == '}'); + next_line (file); + } + break; + } + + /* tab block? */ + if (*file->pos == '\t') + { + char *chp = file->pos; + entry = new_table_entry (file, table_code_entry); + /* determine how many lines are involved - look for ! */ + { + int nr_lines = 0; + int nr_blank_lines = 0; + while (1) + { + if (*file->pos == '\t') + { + nr_lines = nr_lines + nr_blank_lines + 1; + nr_blank_lines = 0; + next_line (file); + } + else + { + file->pos = skip_spaces (file->pos); + if (*file->pos != '\n') + break; + nr_blank_lines++; + next_line (file); + } + } + set_nr_table_entry_fields (entry, nr_lines); + } + /* now enter each line */ + { + int line_nr; + for (line_nr = 0; line_nr < entry->nr_fields; line_nr++) + { + if (*chp == '\t') + entry->field[line_nr] = chp + 1; + else + entry->field[line_nr] = ""; /* blank */ + chp = skip_to_null (chp) + 1; + } + } + break; + } + + /* cpp directive? */ + if (file->pos[0] == '#') + { + char *chp = skip_spaces (file->pos + 1); + + /* cpp line-nr directive - # "" */ + if (isdigit (*chp) + && *skip_digits (chp) == ' ' + && *skip_spaces (skip_digits (chp)) == '"') + { + int line_nr; + char *file_name; + file->pos = chp; + /* parse the number */ + line_nr = atoi (file->pos) - 1; + /* skip to the file name */ + while (file->pos[0] != '0' + && file->pos[0] != '"' && file->pos[0] != '\0') + file->pos++; + if (file->pos[0] != '"') + error (&file->real_line, + "Missing opening quote in cpp directive\n"); + /* parse the file name */ + file->pos++; + file_name = file->pos; + while (file->pos[0] != '"' && file->pos[0] != '\0') + file->pos++; + if (file->pos[0] != '"') + error (&file->real_line, + "Missing closing quote in cpp directive\n"); + file->pos[0] = '\0'; + file->pos++; + file->pos = skip_to_nl (file->pos); + if (file->pos[0] != '\n') + error (&file->real_line, + "Missing newline in cpp directive\n"); + file->pseudo_line.file_name = file_name; + file->pseudo_line.line_nr = line_nr; + next_line (file); + continue; + } + + /* #define and #undef - not implemented yet */ + + /* Old style # comment */ + next_line (file); + continue; + } + + /* blank line or end-of-file? */ + file->pos = skip_spaces (file->pos); + if (*file->pos == '\0') + error (&file->pseudo_line, "Missing at end of file\n"); + if (*file->pos == '\n') + { + next_line (file); + continue; + } + + /* comment - leading // or # - skip */ + if ((file->pos[0] == '/' && file->pos[1] == '/') + || (file->pos[0] == '#')) + { + next_line (file); + continue; + } + + /* colon field */ + { + char *chp = file->pos; + entry = new_table_entry (file, table_colon_entry); + next_line (file); + /* figure out how many fields */ + { + int nr_fields = 1; + char *tmpch = chp; + while (1) + { + tmpch = skip_to_separator (tmpch, "\\:"); + if (*tmpch == '\\') + { + /* eat the escaped character */ + char *cp = tmpch; + while (cp[1] != '\0') + { + cp[0] = cp[1]; + cp++; + } + cp[0] = '\0'; + tmpch++; + } + else if (*tmpch != ':') + break; + else + { + *tmpch = '\0'; + tmpch++; + nr_fields++; + } + } + set_nr_table_entry_fields (entry, nr_fields); + } + /* now parse them */ + { + int field_nr; + for (field_nr = 0; field_nr < entry->nr_fields; field_nr++) + { + chp = skip_spaces (chp); + entry->field[field_nr] = chp; + chp = skip_to_null (chp); + *back_spaces (entry->field[field_nr], chp) = '\0'; + chp++; + } + } + break; + } + + } + + ASSERT (entry == NULL || entry->field[entry->nr_fields] == NULL); + return entry; +} + +extern void +table_print_code (lf *file, table_entry *entry) +{ + int field_nr; + int nr = 0; + for (field_nr = 0; field_nr < entry->nr_fields; field_nr++) + { + char *chp = entry->field[field_nr]; + int in_bit_field = 0; + if (*chp == '#') + lf_indent_suppress (file); + while (*chp != '\0') + { + if (chp[0] == '{' && !isspace (chp[1]) && chp[1] != '\0') + { + in_bit_field = 1; + nr += lf_putchr (file, '_'); + } + else if (in_bit_field && chp[0] == ':') + { + nr += lf_putchr (file, '_'); + } + else if (in_bit_field && *chp == '}') + { + nr += lf_putchr (file, '_'); + in_bit_field = 0; + } + else + { + nr += lf_putchr (file, *chp); + } + chp++; + } + if (in_bit_field) + { + line_ref line = *entry->line; + line.line_nr += field_nr; + error (&line, "Bit field brace miss match\n"); + } + nr += lf_putchr (file, '\n'); + } +} + + + +void +dump_line_ref (lf *file, char *prefix, const line_ref *line, char *suffix) +{ + lf_printf (file, "%s(line_ref*) 0x%lx", prefix, (long) line); + if (line != NULL) + { + lf_indent (file, +1); + lf_printf (file, "\n(line_nr %d)", line->line_nr); + lf_printf (file, "\n(file_name %s)", line->file_name); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + + +static const char * +table_entry_type_to_str (table_entry_type type) +{ + switch (type) + { + case table_code_entry: + return "code-entry"; + case table_colon_entry: + return "colon-entry"; + } + return "*invalid*"; +} + +void +dump_table_entry (lf *file, + char *prefix, const table_entry *entry, char *suffix) +{ + lf_printf (file, "%s(table_entry*) 0x%lx", prefix, (long) entry); + if (entry != NULL) + { + int field; + lf_indent (file, +1); + dump_line_ref (file, "\n(line ", entry->line, ")"); + lf_printf (file, "\n(type %s)", table_entry_type_to_str (entry->type)); + lf_printf (file, "\n(nr_fields %d)", entry->nr_fields); + lf_printf (file, "\n(fields"); + lf_indent (file, +1); + for (field = 0; field < entry->nr_fields; field++) + lf_printf (file, "\n\"%s\"", entry->field[field]); + lf_indent (file, -1); + lf_printf (file, ")"); + lf_indent (file, -1); + } + lf_printf (file, "%s", suffix); +} + + +#ifdef MAIN +int +main (int argc, char **argv) +{ + table *t; + table_entry *entry; + lf *l; + int line_nr; + + if (argc != 2) + { + printf ("Usage: table \n"); + exit (1); + } + + t = table_open (argv[1]); + l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-table"); + + line_nr = 0; + do + { + char line[10]; + entry = table_read (t); + line_nr++; + sprintf (line, "(%d ", line_nr); + dump_table_entry (l, line, entry, ")\n"); + } + while (entry != NULL); + + return 0; +} +#endif
table.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen-support.h =================================================================== --- gen-support.h (nonexistent) +++ gen-support.h (revision 841) @@ -0,0 +1,25 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +extern void gen_support_h (lf *file, insn_table *table); + +extern void gen_support_c (lf *file, insn_table *table);
gen-support.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gen-icache.h =================================================================== --- gen-icache.h (nonexistent) +++ gen-icache.h (revision 841) @@ -0,0 +1,79 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +/* Output code to manipulate the instruction cache: either create it + or reference it */ + +typedef enum +{ + declare_variables, + define_variables, + undef_variables, +} +icache_decl_type; + +typedef enum +{ + do_not_use_icache = 0, + get_values_from_icache = 0x1, + put_values_in_icache = 0x2, + both_values_and_icache = 0x3, +} +icache_body_type; + +extern void print_icache_body + (lf *file, + insn_entry * instruction, + opcode_bits *expanded_bits, + cache_entry *cache_rules, + icache_decl_type what_to_declare, + icache_body_type what_to_do, int nr_prefetched_words); + + +/* Output an instruction cache decode function */ + +extern void print_icache_declaration + (lf *file, + insn_entry * insn, + opcode_bits *expanded_bits, + insn_opcodes *opcodes, int nr_prefetched_words); + +extern void print_icache_definition + (lf *file, + insn_entry * insn, + opcode_bits *expanded_bits, + insn_opcodes *opcodes, cache_entry *cache_rules, int nr_prefetched_words); + + +/* Output an instruction cache support function */ + +extern function_entry_handler print_icache_internal_function_declaration; +extern function_entry_handler print_icache_internal_function_definition; + + +/* Output the instruction cache table data structure */ + +extern void print_icache_struct + (lf *file, insn_table *instructions, cache_entry *cache_rules); + + +/* Output a single instructions decoder */
gen-icache.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: filter.h =================================================================== --- filter.h (nonexistent) +++ filter.h (revision 841) @@ -0,0 +1,69 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +/* NB, an empty filter is NULL */ +typedef struct _filter filter; + + +/* parse the list merging any flags into the filter */ + +extern void filter_parse (filter **filters, const char *filt); + + +/* add the second filter to the first */ + +extern void filter_add (filter **filters, filter *add); + + + +/* returns true if SUB is a strict subset of SUPER. For an empty set + is a member of any set */ + +extern int filter_is_subset (filter *superset, filter *subset); + + +/* return true if there is at least one member common to the two + filters */ + +extern int filter_is_common (filter *l, filter *r); + + +/* returns the index (pos + 1) if the name is in the filter. */ + +extern int filter_is_member (filter *set, const char *flag); + + +/* returns true if one of the flags is not present in the filter. + === !filter_is_subset (filter_parse (NULL, flags), filters) */ +int is_filtered_out (filter *filters, const char *flags); + + +/* returns the next member of the filter set that follows MEMBER. + Member does not need to be an elememt of the filter set. Next of + "" is the first non-empty member */ +char *filter_next (filter *set, char *member); + + + +/* for debugging */ + +extern void dump_filter (lf *file, char *prefix, filter *filt, char *suffix);
filter.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: misc.c =================================================================== --- misc.c (nonexistent) +++ misc.c (revision 841) @@ -0,0 +1,274 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + + +#include +#include +#include + +#include "config.h" +#include "misc.h" + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#else +#ifdef HAVE_STRINGS_H +#include +#endif +#endif + +/* NB: Because warning and error can be interchanged, neither append a + trailing '\n' */ + +void +error (const line_ref *line, char *msg, ...) +{ + va_list ap; + if (line != NULL) + fprintf (stderr, "%s:%d: ", line->file_name, line->line_nr); + va_start (ap, msg); + vfprintf (stderr, msg, ap); + va_end (ap); + exit (1); +} + +void +warning (const line_ref *line, char *msg, ...) +{ + va_list ap; + if (line != NULL) + fprintf (stderr, "%s:%d: warning: ", line->file_name, line->line_nr); + va_start (ap, msg); + vfprintf (stderr, msg, ap); + va_end (ap); +} + +void +notify (const line_ref *line, char *msg, ...) +{ + va_list ap; + if (line != NULL) + fprintf (stdout, "%s %d: info: ", line->file_name, line->line_nr); + va_start (ap, msg); + vfprintf (stdout, msg, ap); + va_end (ap); +} + +void * +zalloc (long size) +{ + void *memory = malloc (size); + if (memory == NULL) + ERROR ("zalloc failed"); + memset (memory, 0, size); + return memory; +} + + +unsigned long long +a2i (const char *a) +{ + int neg = 0; + int base = 10; + unsigned long long num = 0; + int looping; + + while (isspace (*a)) + a++; + + if (strcmp (a, "true") == 0 || strcmp (a, "TRUE") == 0) + return 1; + + if (strcmp (a, "false") == 0 || strcmp (a, "false") == 0) + return 0; + + if (*a == '-') + { + neg = 1; + a++; + } + + if (*a == '0') + { + if (a[1] == 'x' || a[1] == 'X') + { + a += 2; + base = 16; + } + else if (a[1] == 'b' || a[1] == 'b') + { + a += 2; + base = 2; + } + else + base = 8; + } + + looping = 1; + while (looping) + { + int ch = *a++; + + switch (base) + { + default: + looping = 0; + break; + + case 2: + if (ch >= '0' && ch <= '1') + { + num = (num * 2) + (ch - '0'); + } + else + { + looping = 0; + } + break; + + case 10: + if (ch >= '0' && ch <= '9') + { + num = (num * 10) + (ch - '0'); + } + else + { + looping = 0; + } + break; + + case 8: + if (ch >= '0' && ch <= '7') + { + num = (num * 8) + (ch - '0'); + } + else + { + looping = 0; + } + break; + + case 16: + if (ch >= '0' && ch <= '9') + { + num = (num * 16) + (ch - '0'); + } + else if (ch >= 'a' && ch <= 'f') + { + num = (num * 16) + (ch - 'a' + 10); + } + else if (ch >= 'A' && ch <= 'F') + { + num = (num * 16) + (ch - 'A' + 10); + } + else + { + looping = 0; + } + break; + } + } + + if (neg) + num = -num; + + return num; +} + +unsigned +target_a2i (int ms_bit_nr, const char *a) +{ + if (ms_bit_nr) + return (ms_bit_nr - a2i (a)); + else + return a2i (a); +} + +unsigned +i2target (int ms_bit_nr, unsigned bit) +{ + if (ms_bit_nr) + return ms_bit_nr - bit; + else + return bit; +} + + +int +name2i (const char *names, const name_map * map) +{ + const name_map *curr; + const char *name = names; + while (*name != '\0') + { + /* find our name */ + char *end = strchr (name, ','); + char *next; + unsigned len; + if (end == NULL) + { + end = strchr (name, '\0'); + next = end; + } + else + { + next = end + 1; + } + len = end - name; + /* look it up */ + curr = map; + while (curr->name != NULL) + { + if (strncmp (curr->name, name, len) == 0 + && strlen (curr->name) == len) + return curr->i; + curr++; + } + name = next; + } + /* nothing found, possibly return a default */ + curr = map; + while (curr->name != NULL) + curr++; + if (curr->i >= 0) + return curr->i; + else + error (NULL, "%s contains no valid names", names); + return 0; +} + +const char * +i2name (const int i, const name_map * map) +{ + while (map->name != NULL) + { + if (map->i == i) + return map->name; + map++; + } + error (NULL, "map lookup failed for %d\n", i); + return NULL; +}
misc.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: table.h =================================================================== --- table.h (nonexistent) +++ table.h (revision 841) @@ -0,0 +1,139 @@ +/* The IGEN simulator generator for GDB, the GNU Debugger. + + Copyright 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + Contributed by Andrew Cagney. + + 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 . */ + + +/* Read a table, line by line, from a file. + + A table line has several forms: + + Field line: + + { ":" } + type == table_colon_entry + + Fields points to a NULL terminated list of pointers. + + Tab indented block: + + { } + type == table_code_entry + + The leading tab at the start of each line is discarded. + fields[i] is the i'th line with the discarded. + + + Code block: + + "{" { } "}" + type == table_code_entry + + The leading/trailing {/} lines are discarded. + Lines containing two leading spaces have those spaces striped. + fields[i] is the i'th line with the discarded. + + In addition, the table parser reconises and handles internally the + following (when not in a code block): + + "#" '"' '"' + + As per CPP/CC, treat following lines as if they were taken from + starting at + + No support for CPP's "#if/#else/#endif" style conditions are + planned. */ + +typedef struct _table table; + +typedef enum +{ + table_colon_entry, + table_code_entry, +} +table_entry_type; + + +typedef struct _table_entry table_entry; +struct _table_entry +{ + table *file; + line_ref *line; + table_entry_type type; + int nr_fields; + char **field; +}; + +/* List of directories to search when opening a pushed file. Current + directory is always searched first */ +typedef struct _table_include table_include; +struct _table_include +{ + char *dir; + table_include *next; +}; + + +/* Open/read a table file. Since the file is read once during open + (and then closed immediatly) there is no close method. */ + +extern table *table_open (const char *file_name); + +extern table_entry *table_read (table *file); + + +/* Push the the state of the current file and open FILE_NAME. When + the end of FILE_NAME is reached, return to the pushed file */ + +extern void table_push + (table *file, line_ref *line, table_include *search, const char *file_name); + + +/* Expand the specified field_nr using the internal expansion table. + A field is only expanded when explicitly specified. */ + +extern void table_expand_field (table_entry *entry, int field_nr); + + +/* Given a code entry, write the code to FILE. Since any + leading/trailing braces were striped as part of the read, they are + not written. */ + +extern void table_print_code (lf *file, table_entry *entry); + + +/* Debugging */ + +extern void dump_line_ref + (lf *file, char *prefix, const line_ref *line, char *suffix); + +extern void dump_table_entry + (lf *file, char *prefix, const table_entry *entry, char *suffix); + + + +/* Utilities for skipping around text */ + +extern char *skip_digits (char *chp); + +extern char *skip_spaces (char *chp); + +extern char *skip_to_separator (char *chp, char *separators); + +extern char *back_spaces (char *start, char *chp);
table.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.