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-old/gdb-7.1/sim/arm
    from Rev 227 to Rev 816
    Reverse comparison

Rev 227 → Rev 816

/dbg_rdi.h
0,0 → 1,338
/* dbg_rdi.h -- ARMulator RDI interface: ARM6 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
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 2 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, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
 
#ifndef dbg_rdi__h
#define dbg_rdi__h
 
/***************************************************************************\
* Error Codes *
\***************************************************************************/
 
#define RDIError_NoError 0
 
#define RDIError_Reset 1
#define RDIError_UndefinedInstruction 2
#define RDIError_SoftwareInterrupt 3
#define RDIError_PrefetchAbort 4
#define RDIError_DataAbort 5
#define RDIError_AddressException 6
#define RDIError_IRQ 7
#define RDIError_FIQ 8
#define RDIError_Error 9
#define RDIError_BranchThrough0 10
 
#define RDIError_NotInitialised 128
#define RDIError_UnableToInitialise 129
#define RDIError_WrongByteSex 130
#define RDIError_UnableToTerminate 131
#define RDIError_BadInstruction 132
#define RDIError_IllegalInstruction 133
#define RDIError_BadCPUStateSetting 134
#define RDIError_UnknownCoPro 135
#define RDIError_UnknownCoProState 136
#define RDIError_BadCoProState 137
#define RDIError_BadPointType 138
#define RDIError_UnimplementedType 139
#define RDIError_BadPointSize 140
#define RDIError_UnimplementedSize 141
#define RDIError_NoMorePoints 142
#define RDIError_BreakpointReached 143
#define RDIError_WatchpointAccessed 144
#define RDIError_NoSuchPoint 145
#define RDIError_ProgramFinishedInStep 146
#define RDIError_UserInterrupt 147
#define RDIError_CantSetPoint 148
#define RDIError_IncompatibleRDILevels 149
 
#define RDIError_CantLoadConfig 150
#define RDIError_BadConfigData 151
#define RDIError_NoSuchConfig 152
#define RDIError_BufferFull 153
#define RDIError_OutOfStore 154
#define RDIError_NotInDownload 155
#define RDIError_PointInUse 156
#define RDIError_BadImageFormat 157
#define RDIError_TargetRunning 158
 
#define RDIError_LittleEndian 240
#define RDIError_BigEndian 241
#define RDIError_SoftInitialiseError 242
 
#define RDIError_InsufficientPrivilege 253
#define RDIError_UnimplementedMessage 254
#define RDIError_UndefinedMessage 255
 
/***************************************************************************\
* RDP Message Numbers *
\***************************************************************************/
 
#define RDP_Start (unsigned char)0x0
#define RDP_End (unsigned char)0x1
#define RDP_Read (unsigned char)0x2
#define RDP_Write (unsigned char)0x3
#define RDP_CPUread (unsigned char)0x4
#define RDP_CPUwrite (unsigned char)0x5
#define RDP_CPread (unsigned char)0x6
#define RDP_CPwrite (unsigned char)0x7
#define RDP_SetBreak (unsigned char)0xa
#define RDP_ClearBreak (unsigned char)0xb
#define RDP_SetWatch (unsigned char)0xc
#define RDP_ClearWatch (unsigned char)0xd
#define RDP_Execute (unsigned char)0x10
#define RDP_Step (unsigned char)0x11
#define RDP_Info (unsigned char)0x12
#define RDP_OSOpReply (unsigned char)0x13
 
#define RDP_AddConfig (unsigned char)0x14
#define RDP_LoadConfigData (unsigned char)0x15
#define RDP_SelectConfig (unsigned char)0x16
#define RDP_LoadAgent (unsigned char)0x17
 
#define RDP_Stopped (unsigned char)0x20
#define RDP_OSOp (unsigned char)0x21
#define RDP_Fatal (unsigned char)0x5e
#define RDP_Return (unsigned char)0x5f
#define RDP_Reset (unsigned char)0x7f
 
/***************************************************************************\
* Other RDI values *
\***************************************************************************/
 
#define RDISex_Little 0 /* the byte sex of the debuggee */
#define RDISex_Big 1
#define RDISex_DontCare 2
 
#define RDIPoint_EQ 0 /* the different types of break/watchpoints */
#define RDIPoint_GT 1
#define RDIPoint_GE 2
#define RDIPoint_LT 3
#define RDIPoint_LE 4
#define RDIPoint_IN 5
#define RDIPoint_OUT 6
#define RDIPoint_MASK 7
 
#define RDIPoint_Inquiry 64 /* ORRed with point type in extended RDP */
#define RDIPoint_Handle 128 /* messages */
 
#define RDIWatch_ByteRead 1 /* types of data accesses to watch for */
#define RDIWatch_HalfRead 2
#define RDIWatch_WordRead 4
#define RDIWatch_ByteWrite 8
#define RDIWatch_HalfWrite 16
#define RDIWatch_WordWrite 32
 
#define RDIReg_R15 (1L << 15) /* mask values for CPU */
#define RDIReg_PC (1L << 16)
#define RDIReg_CPSR (1L << 17)
#define RDIReg_SPSR (1L << 18)
#define RDINumCPURegs 19
 
#define RDINumCPRegs 10 /* current maximum */
 
#define RDIMode_Curr 255
 
/* Bits set in return value from RDIInfo_Target */
#define RDITarget_LogSpeed 0x0f
#define RDITarget_HW 0x10 /* else emulator */
#define RDITarget_AgentMaxLevel 0xe0
#define RDITarget_AgentLevelShift 5
#define RDITarget_DebuggerMinLevel 0x700
#define RDITarget_DebuggerLevelShift 8
#define RDITarget_CanReloadAgent 0x800
#define RDITarget_CanInquireLoadSize 0x1000
 
/* Bits set in return value from RDIInfo_Step */
#define RDIStep_Multiple 1
#define RDIStep_PCChange 2
#define RDIStep_Single 4
 
/* Bits set in return value from RDIInfo_Points */
#define RDIPointCapability_Comparison 1
#define RDIPointCapability_Range 2
/* 4 to 128 are RDIWatch_xx{Read,Write} left-shifted by two */
#define RDIPointCapability_Mask 256
#define RDIPointCapability_Status 512 /* Point status enquiries available */
 
/* RDI_Info subcodes */
#define RDIInfo_Target 0
#define RDIInfo_Points 1
#define RDIInfo_Step 2
#define RDIInfo_MMU 3
#define RDIInfo_DownLoad 4 /* Inquires whether configuration download
and selection is available.
*/
#define RDIInfo_SemiHosting 5 /* Inquires whether RDISemiHosting_* RDI_Info
calls are available.
*/
#define RDIInfo_CoPro 6 /* Inquires whether CoPro RDI_Info calls are
available.
*/
#define RDIInfo_Icebreaker 7
 
/* The next two are only to be used if the value returned by RDIInfo_Points */
/* has RDIPointCapability_Status set. */
#define RDIPointStatus_Watch 0x80
#define RDIPointStatus_Break 0x81
 
#define RDISignal_Stop 0x100
 
#define RDIVector_Catch 0x180
 
/* The next four are only to be used if RDIInfo_Semihosting returned no error */
#define RDISemiHosting_SetState 0x181
#define RDISemiHosting_GetState 0x182
#define RDISemiHosting_SetVector 0x183
#define RDISemiHosting_GetVector 0x184
 
/* The next two are only to be used if RDIInfo_Icebreaker returned no error */
#define RDIIcebreaker_GetLocks 0x185
#define RDIIcebreaker_SetLocks 0x186
 
/* Only if RDIInfo_Target returned RDITarget_CanInquireLoadSize */
#define RDIInfo_GetLoadSize 0x187
 
#define RDICycles 0x200
#define RDICycles_Size 48
#define RDIErrorP 0x201
 
#define RDISet_Cmdline 0x300
#define RDISet_RDILevel 0x301
#define RDISet_Thread 0x302
 
/* The next two are only to be used if RDIInfo_CoPro returned no error */
#define RDIInfo_DescribeCoPro 0x400
#define RDIInfo_RequestCoProDesc 0x401
 
#define RDIInfo_Log 0x800
#define RDIInfo_SetLog 0x801
 
typedef unsigned long PointHandle;
typedef unsigned long ThreadHandle;
#define RDINoPointHandle ((PointHandle)-1L)
#define RDINoHandle ((ThreadHandle)-1L)
 
struct Dbg_ConfigBlock;
struct Dbg_HostosInterface;
struct Dbg_MCState;
typedef int rdi_open_proc (unsigned type,
struct Dbg_ConfigBlock const *config,
struct Dbg_HostosInterface const *i,
struct Dbg_MCState *dbg_state);
typedef int rdi_close_proc (void);
typedef int rdi_read_proc (ARMword source, void *dest, unsigned *nbytes);
typedef int rdi_write_proc (const void *source, ARMword dest,
unsigned *nbytes);
typedef int rdi_CPUread_proc (unsigned mode, unsigned long mask,
ARMword * state);
typedef int rdi_CPUwrite_proc (unsigned mode, unsigned long mask,
ARMword const *state);
typedef int rdi_CPread_proc (unsigned CPnum, unsigned long mask,
ARMword * state);
typedef int rdi_CPwrite_proc (unsigned CPnum, unsigned long mask,
ARMword const *state);
typedef int rdi_setbreak_proc (ARMword address, unsigned type, ARMword bound,
PointHandle * handle);
typedef int rdi_clearbreak_proc (PointHandle handle);
typedef int rdi_setwatch_proc (ARMword address, unsigned type,
unsigned datatype, ARMword bound,
PointHandle * handle);
typedef int rdi_clearwatch_proc (PointHandle handle);
typedef int rdi_execute_proc (PointHandle * handle);
typedef int rdi_step_proc (unsigned ninstr, PointHandle * handle);
typedef int rdi_info_proc (unsigned type, ARMword * arg1, ARMword * arg2);
typedef int rdi_pointinq_proc (ARMword * address, unsigned type,
unsigned datatype, ARMword * bound);
 
typedef enum
{
RDI_ConfigCPU,
RDI_ConfigSystem
}
RDI_ConfigAspect;
 
typedef enum
{
RDI_MatchAny,
RDI_MatchExactly,
RDI_MatchNoEarlier
}
RDI_ConfigMatchType;
 
typedef int rdi_addconfig_proc (unsigned long nbytes);
typedef int rdi_loadconfigdata_proc (unsigned long nbytes, char const *data);
typedef int rdi_selectconfig_proc (RDI_ConfigAspect aspect, char const *name,
RDI_ConfigMatchType matchtype,
unsigned versionreq, unsigned *versionp);
 
typedef char *getbufferproc (void *getbarg, unsigned long *sizep);
typedef int rdi_loadagentproc (ARMword dest, unsigned long size,
getbufferproc * getb, void *getbarg);
 
typedef struct
{
int itemmax;
char const *const *names;
}
RDI_NameList;
 
typedef RDI_NameList const *rdi_namelistproc (void);
 
typedef int rdi_errmessproc (char *buf, int buflen, int errno);
 
struct RDIProcVec
{
char rditypename[12];
 
rdi_open_proc *open;
rdi_close_proc *close;
rdi_read_proc *read;
rdi_write_proc *write;
rdi_CPUread_proc *CPUread;
rdi_CPUwrite_proc *CPUwrite;
rdi_CPread_proc *CPread;
rdi_CPwrite_proc *CPwrite;
rdi_setbreak_proc *setbreak;
rdi_clearbreak_proc *clearbreak;
rdi_setwatch_proc *setwatch;
rdi_clearwatch_proc *clearwatch;
rdi_execute_proc *execute;
rdi_step_proc *step;
rdi_info_proc *info;
/* V2 RDI */
rdi_pointinq_proc *pointinquiry;
 
/* These three useable only if RDIInfo_DownLoad returns no error */
rdi_addconfig_proc *addconfig;
rdi_loadconfigdata_proc *loadconfigdata;
rdi_selectconfig_proc *selectconfig;
 
rdi_namelistproc *drivernames;
rdi_namelistproc *cpunames;
 
rdi_errmessproc *errmess;
 
/* Only if RDIInfo_Target returns a value with RDITarget_LoadAgent set */
rdi_loadagentproc *loadagent;
};
 
#endif
 
extern unsigned int swi_mask;
 
#define SWI_MASK_DEMON (1 << 0)
#define SWI_MASK_ANGEL (1 << 1)
#define SWI_MASK_REDBOOT (1 << 2)
dbg_rdi.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 =================================================================== --- configure (nonexistent) +++ configure (revision 816) @@ -0,0 +1,5883 @@ +#! /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="Makefile.in" +# 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 +cgen_breaks +COPRO +REPORT_BUGS_TEXI +REPORT_BUGS_TO +PKGVERSION +sim_profile +sim_trace +sim_stdio +sim_debug +sim_cflags +sim_bswap +MAINT +EGREP +GREP +CPP +CATOBJEXT +GENCAT +INSTOBJEXT +DATADIRNAME +CATALOGS +POSUB +GMSGFMT +XGETTEXT +INCINTL +LIBINTL_DEP +LIBINTL +USE_NLS +RANLIB +AR +HDEFINES +CC_FOR_BUILD +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +WERROR_CFLAGS +WARN_CFLAGS +sim_xor_endian +sim_stdcall +sim_smp +sim_reserved_bits +sim_regparm +sim_packages +sim_inline +sim_hw +sim_hw_objs +sim_hw_cflags +sim_default_model +sim_scache +sim_float +sim_hostendian +sim_endian +sim_bitsize +sim_assert +sim_alignment +sim_environment +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_zlib +enable_maintainer_mode +enable_sim_bswap +enable_sim_cflags +enable_sim_debug +enable_sim_stdio +enable_sim_trace +enable_sim_profile +with_pkgversion +with_bugurl +' + 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-maintainer-mode Enable developer functionality. + --enable-sim-bswap Use Host specific BSWAP instruction. + --enable-sim-cflags=opts Extra CFLAGS for use in building simulator + --enable-sim-debug=opts Enable debugging flags + --enable-sim-stdio Specify whether to use stdio for console input/output. + --enable-sim-trace=opts Enable tracing flags + --enable-sim-profile=opts Enable profiling flags + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-zlib include zlib support (auto/yes/no) default=auto + --with-pkgversion=PKG Use PKG in the version string in place of "GDB" + --with-bugurl=URL Direct users to URL to report a bug + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L 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 + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.64. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + ac_site_file1=$CONFIG_SITE +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_config_headers="$ac_config_headers config.h:config.in" + + +# This file contains common code used by all simulators. +# +# SIM_AC_COMMON invokes AC macros used by all simulators and by the common +# directory. It is intended to be invoked before any target specific stuff. +# SIM_AC_OUTPUT is a cover function to AC_OUTPUT to generate the Makefile. +# It is intended to be invoked last. +# +# The simulator's configure.in should look like: +# +# dnl Process this file with autoconf to produce a configure script. +# sinclude(../common/aclocal.m4) +# AC_PREREQ(2.5)dnl +# AC_INIT(Makefile.in) +# +# SIM_AC_COMMON +# +# ... target specific stuff ... +# +# SIM_AC_OUTPUT + +# Include global overrides and fixes for Autoconf. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +sim_inline="-DDEFAULT_INLINE=0" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# intl sister-directory configuration rules. +# + +# The idea behind this macro is that there's no need to repeat all the +# autoconf probes done by the intl directory - it's already done them +# for us. In fact, there's no need even to look at the cache for the +# answers. All we need to do is nab a few pieces of information. +# The intl directory is set up to make this easy, by generating a +# small file which can be sourced as a shell script; then we produce +# the necessary substitutions and definitions for this directory. + + + +# Autoconf M4 include file defining utility macros for complex Canadian +# cross builds. + + + + + + + + + +#### +# _NCN_TOOL_PREFIXES: Some stuff that oughtta be done in AC_CANONICAL_SYSTEM +# or AC_INIT. +# These demand that AC_CANONICAL_SYSTEM be called beforehand. + +#### +# NCN_STRICT_CHECK_TOOLS(variable, progs-to-check-for,[value-if-not-found],[path]) +# Like plain AC_CHECK_TOOLS, but require prefix if build!=host. + + +#### +# NCN_STRICT_CHECK_TARGET_TOOLS(variable, progs-to-check-for,[value-if-not-found],[path]) +# Like CVS Autoconf AC_CHECK_TARGET_TOOLS, but require prefix if build!=target. + + + +# Backported from Autoconf 2.5x; can go away when and if +# we switch. Put the OS path separator in $PATH_SEPARATOR. + + + + +# ACX_HAVE_GCC_FOR_TARGET +# Check if the variable GCC_FOR_TARGET really points to a GCC binary. + + +# ACX_CHECK_INSTALLED_TARGET_TOOL(VAR, PROG) +# Searching for installed target binutils. We need to take extra care, +# else we may find the wrong assembler, linker, etc., and lose. +# +# First try --with-build-time-tools, if specified. +# +# For build != host, we ask the installed GCC for the name of the tool it +# uses, and accept it if it is an absolute path. This is because the +# only good choice for a compiler is the same GCC version that is being +# installed (or we couldn't make target libraries), and we assume that +# on the host system we'll have not only the same GCC version, but also +# the same binutils version. +# +# For build == host, search the same directories that the installed +# compiler will search. We used to do this for the assembler, linker, +# and nm only; for simplicity of configuration, however, we extend this +# criterion to tools (such as ar and ranlib) that are never invoked by +# the compiler, to avoid mismatches. +# +# Also note we have to check MD_EXEC_PREFIX before checking the user's path +# if build == target. This makes the most sense only when bootstrapping, +# but we also do so when build != host. In this case, we hope that the +# build and host systems will have similar contents of MD_EXEC_PREFIX. +# +# If we do not find a suitable binary, then try the user's path. + + +### +# AC_PROG_CPP_WERROR +# Used for autoconf 2.5x to force AC_PREPROC_IFELSE to reject code which +# triggers warnings from the preprocessor. Will be in autoconf 2.58. +# For now, using this also overrides header checks to use only the +# preprocessor (matches 2.13 behavior; matching 2.58's behavior is a +# bit harder from here). +# Eventually autoconf will default to checking headers with the compiler +# instead, and we'll have to do this differently. + +# AC_PROG_CPP_WERROR + +# Test for GNAT. +# We require the gnatbind program, and a compiler driver that +# understands Ada. We use the user's CC setting, already found, +# and possibly add $1 to the command-line parameters. +# +# Sets the shell variable have_gnat to yes or no as appropriate, and +# substitutes GNATBIND and GNATMAKE. + + + + + + + + + + + + + + + + + + + + + + + + + +# Bugs in autoconf 2.59 break the call to SIM_AC_COMMON, hack around +# it by inlining the macro's contents. +# This file contains common code used by all simulators. +# +# common.m4 invokes AC macros used by all simulators and by the common +# directory. It is intended to be included before any target specific +# stuff. SIM_AC_OUTPUT is a cover function to AC_OUTPUT to generate +# the Makefile. It is intended to be invoked last. +# +# The simulator's configure.in should look like: +# +# dnl Process this file with autoconf to produce a configure script. +# AC_PREREQ(2.5)dnl +# AC_INIT(Makefile.in) +# AC_CONFIG_HEADER(config.h:config.in) +# +# sinclude(../common/aclocal.m4) +# sinclude(../common/common.m4) +# +# ... target specific stuff ... + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + for ac_t in install-sh install.sh shtool; do + if test -f "$ac_dir/$ac_t"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/$ac_t -c" + break 2 + fi + done +done +if test -z "$ac_aux_dir"; then + as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if test "${ac_cv_build+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if test "${ac_cv_target+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +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"` + +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 + +# 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' + + +# Put a plausible default for CC_FOR_BUILD in Makefile. +if test "x$cross_compiling" = "xno"; then + CC_FOR_BUILD='$(CC)' +else + CC_FOR_BUILD=gcc +fi + + + + +AR=${AR-ar} + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + +ALL_LINGUAS= +# If we haven't got the data from the intl directory, +# assume NLS is disabled. +USE_NLS=no +LIBINTL= +LIBINTL_DEP= +INCINTL= +XGETTEXT= +GMSGFMT= +POSUB= + +if test -f ../../intl/config.intl; then + . ../../intl/config.intl +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 +$as_echo_n "checking whether NLS is requested... " >&6; } +if test x"$USE_NLS" != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define ENABLE_NLS 1" >>confdefs.h + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for catalogs to be installed" >&5 +$as_echo_n "checking for catalogs to be installed... " >&6; } + # Look for .po and .gmo files in the source directory. + CATALOGS= + XLINGUAS= + for cat in $srcdir/po/*.gmo $srcdir/po/*.po; do + # If there aren't any .gmo files the shell will give us the + # literal string "../path/to/srcdir/po/*.gmo" which has to be + # weeded out. + case "$cat" in *\**) + continue;; + esac + # The quadruple backslash is collapsed to a double backslash + # by the backticks, then collapsed again by the double quotes, + # leaving us with one backslash in the sed expression (right + # before the dot that mustn't act as a wildcard). + cat=`echo $cat | sed -e "s!$srcdir/po/!!" -e "s!\\\\.po!.gmo!"` + lang=`echo $cat | sed -e "s!\\\\.gmo!!"` + # The user is allowed to set LINGUAS to a list of languages to + # install catalogs for. If it's empty that means "all of them." + if test "x$LINGUAS" = x; then + CATALOGS="$CATALOGS $cat" + XLINGUAS="$XLINGUAS $lang" + else + case "$LINGUAS" in *$lang*) + CATALOGS="$CATALOGS $cat" + XLINGUAS="$XLINGUAS $lang" + ;; + esac + fi + done + LINGUAS="$XLINGUAS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINGUAS" >&5 +$as_echo "$LINGUAS" >&6; } + + + DATADIRNAME=share + + INSTOBJEXT=.mo + + GENCAT=gencat + + CATOBJEXT=.gmo + +fi + +# Check for common headers. +# FIXME: Seems to me this can cause problems for i386-windows hosts. +# At one point there were hardcoded AC_DEFINE's if ${host} = i386-*-windows*. + +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 unistd.h time.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in sys/time.h sys/resource.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in fcntl.h fpu_control.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_header in dlfcn.h errno.h sys/stat.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +for ac_func in getrusage time sigaction __setfpucw +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# Check for socket libraries +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for bind in -lsocket" >&5 +$as_echo_n "checking for bind in -lsocket... " >&6; } +if test "${ac_cv_lib_socket_bind+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char bind (); +int +main () +{ +return bind (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_bind=yes +else + ac_cv_lib_socket_bind=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_bind" >&5 +$as_echo "$ac_cv_lib_socket_bind" >&6; } +if test "x$ac_cv_lib_socket_bind" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 +$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_gethostbyname=yes +else + ac_cv_lib_nsl_gethostbyname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 +$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } +if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBNSL 1 +_ACEOF + + LIBS="-lnsl $LIBS" + +fi + + +# BFD conditionally uses zlib, so we must link it in if libbfd does, by +# using the same condition. + + # See if the user specified whether he wants zlib support or not. + +# Check whether --with-zlib was given. +if test "${with_zlib+set}" = set; then : + withval=$with_zlib; +else + with_zlib=auto +fi + + + if test "$with_zlib" != "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing zlibVersion" >&5 +$as_echo_n "checking for library containing zlibVersion... " >&6; } +if test "${ac_cv_search_zlibVersion+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 zlibVersion (); +int +main () +{ +return zlibVersion (); + ; + return 0; +} +_ACEOF +for ac_lib in '' z; 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_zlibVersion=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_zlibVersion+set}" = set; then : + break +fi +done +if test "${ac_cv_search_zlibVersion+set}" = set; then : + +else + ac_cv_search_zlibVersion=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_zlibVersion" >&5 +$as_echo "$ac_cv_search_zlibVersion" >&6; } +ac_res=$ac_cv_search_zlibVersion +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + for ac_header in zlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ZLIB_H 1 +_ACEOF + +fi + +done + +fi + + if test "$with_zlib" = "yes" -a "$ac_cv_header_zlib_h" != "yes"; then + as_fn_error "zlib (libz) library was explicitly requested but not found" "$LINENO" 5 + fi + fi + + +. ${srcdir}/../../bfd/configure.host + + + +USE_MAINTAINER_MODE=no +# Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; case "${enableval}" in + yes) MAINT="" USE_MAINTAINER_MODE=yes ;; + no) MAINT="#" ;; + *) as_fn_error "\"--enable-maintainer-mode does not take a value\"" "$LINENO" 5; MAINT="#" ;; +esac +if test x"$silent" != x"yes" && test x"$MAINT" = x""; then + echo "Setting maintainer mode" 6>&1 +fi +else + MAINT="#" +fi + + + +# Check whether --enable-sim-bswap was given. +if test "${enable_sim_bswap+set}" = set; then : + enableval=$enable_sim_bswap; case "${enableval}" in + yes) sim_bswap="-DWITH_BSWAP=1 -DUSE_BSWAP=1";; + no) sim_bswap="-DWITH_BSWAP=0";; + *) as_fn_error "\"--enable-sim-bswap does not take a value\"" "$LINENO" 5; sim_bswap="";; +esac +if test x"$silent" != x"yes" && test x"$sim_bswap" != x""; then + echo "Setting bswap flags = $sim_bswap" 6>&1 +fi +else + sim_bswap="" +fi + + + +# Check whether --enable-sim-cflags was given. +if test "${enable_sim_cflags+set}" = set; then : + enableval=$enable_sim_cflags; case "${enableval}" in + yes) sim_cflags="-O2 -fomit-frame-pointer";; + trace) as_fn_error "\"Please use --enable-sim-debug instead.\"" "$LINENO" 5; sim_cflags="";; + no) sim_cflags="";; + *) sim_cflags=`echo "${enableval}" | sed -e "s/,/ /g"`;; +esac +if test x"$silent" != x"yes" && test x"$sim_cflags" != x""; then + echo "Setting sim cflags = $sim_cflags" 6>&1 +fi +else + sim_cflags="" +fi + + + +# Check whether --enable-sim-debug was given. +if test "${enable_sim_debug+set}" = set; then : + enableval=$enable_sim_debug; case "${enableval}" in + yes) sim_debug="-DDEBUG=7 -DWITH_DEBUG=7";; + no) sim_debug="-DDEBUG=0 -DWITH_DEBUG=0";; + *) sim_debug="-DDEBUG='(${enableval})' -DWITH_DEBUG='(${enableval})'";; +esac +if test x"$silent" != x"yes" && test x"$sim_debug" != x""; then + echo "Setting sim debug = $sim_debug" 6>&1 +fi +else + sim_debug="" +fi + + + +# Check whether --enable-sim-stdio was given. +if test "${enable_sim_stdio+set}" = set; then : + enableval=$enable_sim_stdio; case "${enableval}" in + yes) sim_stdio="-DWITH_STDIO=DO_USE_STDIO";; + no) sim_stdio="-DWITH_STDIO=DONT_USE_STDIO";; + *) as_fn_error "\"Unknown value $enableval passed to --enable-sim-stdio\"" "$LINENO" 5; sim_stdio="";; +esac +if test x"$silent" != x"yes" && test x"$sim_stdio" != x""; then + echo "Setting stdio flags = $sim_stdio" 6>&1 +fi +else + sim_stdio="" +fi + + + +# Check whether --enable-sim-trace was given. +if test "${enable_sim_trace+set}" = set; then : + enableval=$enable_sim_trace; case "${enableval}" in + yes) sim_trace="-DTRACE=1 -DWITH_TRACE=-1";; + no) sim_trace="-DTRACE=0 -DWITH_TRACE=0";; + [-0-9]*) + sim_trace="-DTRACE='(${enableval})' -DWITH_TRACE='(${enableval})'";; + [a-z]*) + sim_trace="" + for x in `echo "$enableval" | sed -e "s/,/ /g"`; do + if test x"$sim_trace" = x; then + sim_trace="-DWITH_TRACE='(TRACE_$x" + else + sim_trace="${sim_trace}|TRACE_$x" + fi + done + sim_trace="$sim_trace)'" ;; +esac +if test x"$silent" != x"yes" && test x"$sim_trace" != x""; then + echo "Setting sim trace = $sim_trace" 6>&1 +fi +else + sim_trace="" +fi + + + +# Check whether --enable-sim-profile was given. +if test "${enable_sim_profile+set}" = set; then : + enableval=$enable_sim_profile; case "${enableval}" in + yes) sim_profile="-DPROFILE=1 -DWITH_PROFILE=-1";; + no) sim_profile="-DPROFILE=0 -DWITH_PROFILE=0";; + [-0-9]*) + sim_profile="-DPROFILE='(${enableval})' -DWITH_PROFILE='(${enableval})'";; + [a-z]*) + sim_profile="" + for x in `echo "$enableval" | sed -e "s/,/ /g"`; do + if test x"$sim_profile" = x; then + sim_profile="-DWITH_PROFILE='(PROFILE_$x" + else + sim_profile="${sim_profile}|PROFILE_$x" + fi + done + sim_profile="$sim_profile)'" ;; +esac +if test x"$silent" != x"yes" && test x"$sim_profile" != x""; then + echo "Setting sim profile = $sim_profile" 6>&1 +fi +else + sim_profile="-DPROFILE=1 -DWITH_PROFILE=-1" +fi + + + + +# Check whether --with-pkgversion was given. +if test "${with_pkgversion+set}" = set; then : + withval=$with_pkgversion; case "$withval" in + yes) as_fn_error "package version not specified" "$LINENO" 5 ;; + no) PKGVERSION= ;; + *) PKGVERSION="($withval) " ;; + esac +else + PKGVERSION="(GDB) " + +fi + + + + + +# Check whether --with-bugurl was given. +if test "${with_bugurl+set}" = set; then : + withval=$with_bugurl; case "$withval" in + yes) as_fn_error "bug URL not specified" "$LINENO" 5 ;; + no) BUGURL= + ;; + *) BUGURL="$withval" + ;; + esac +else + BUGURL="http://www.gnu.org/software/gdb/bugs/" + +fi + + case ${BUGURL} in + "") + REPORT_BUGS_TO= + REPORT_BUGS_TEXI= + ;; + *) + REPORT_BUGS_TO="<$BUGURL>" + REPORT_BUGS_TEXI=@uref{`echo "$BUGURL" | sed 's/@/@@/g'`} + ;; + esac; + + + + +cat >>confdefs.h <<_ACEOF +#define PKGVERSION "$PKGVERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define REPORT_BUGS_TO "$REPORT_BUGS_TO" +_ACEOF + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 +$as_echo_n "checking return type of signal handlers... " >&6; } +if test "${ac_cv_type_signal+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_type_signal=int +else + ac_cv_type_signal=void +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 +$as_echo "$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + + + + +sim_link_files= +sim_link_links= + +sim_link_links=tconfig.h +if test -f ${srcdir}/tconfig.in +then + sim_link_files=tconfig.in +else + sim_link_files=../common/tconfig.in +fi + +# targ-vals.def points to the libc macro description file. +case "${target}" in +*-*-*) TARG_VALS_DEF=../common/nltvals.def ;; +esac +sim_link_files="${sim_link_files} ${TARG_VALS_DEF}" +sim_link_links="${sim_link_links} targ-vals.def" + + +for ac_header in unistd.h stdint.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 + + +COPRO="armcopro.o maverick.o iwmmxt.o" + + + + +ac_sources="$sim_link_files" +ac_dests="$sim_link_links" +while test -n "$ac_sources"; do + set $ac_dests; ac_dest=$1; shift; ac_dests=$* + set $ac_sources; ac_source=$1; shift; ac_sources=$* + ac_config_links_1="$ac_config_links_1 $ac_dest:$ac_source" +done +ac_config_links="$ac_config_links $ac_config_links_1" + +cgen_breaks="" +if grep CGEN_MAINT $srcdir/Makefile.in >/dev/null; then +cgen_breaks="break cgen_rtx_error"; +fi + +ac_config_files="$ac_config_files Makefile.sim:Makefile.in" + +ac_config_files="$ac_config_files Make-common.sim:../common/Make-common.in" + +ac_config_files="$ac_config_files .gdbinit:../common/gdbinit.in" + +ac_config_commands="$ac_config_commands Makefile" + +ac_config_commands="$ac_config_commands stamp-h" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with status $?, using 1 if that was 0. +as_fn_error () +{ + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + fi + $as_echo "$as_me: error: $1" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.64. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_links="$ac_config_links" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration links: +$config_links + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.64, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2009 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +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" ;; + "$ac_config_links_1") CONFIG_LINKS="$CONFIG_LINKS $ac_config_links_1" ;; + "Makefile.sim") CONFIG_FILES="$CONFIG_FILES Makefile.sim:Makefile.in" ;; + "Make-common.sim") CONFIG_FILES="$CONFIG_FILES Make-common.sim:../common/Make-common.in" ;; + ".gdbinit") CONFIG_FILES="$CONFIG_FILES .gdbinit:../common/gdbinit.in" ;; + "Makefile") CONFIG_COMMANDS="$CONFIG_COMMANDS Makefile" ;; + "stamp-h") CONFIG_COMMANDS="$CONFIG_COMMANDS stamp-h" ;; + + *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +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 :L $CONFIG_LINKS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$tmp/config.h" "$ac_file" \ + || as_fn_error "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error "could not create -" "$LINENO" 5 + fi + ;; + :L) + # + # CONFIG_LINK + # + + if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then + : + else + # Prefer the file from the source tree if names are identical. + if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then + ac_source=$srcdir/$ac_source + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5 +$as_echo "$as_me: linking $ac_source to $ac_file" >&6;} + + if test ! -r "$ac_source"; then + as_fn_error "$ac_source: file not found" "$LINENO" 5 + fi + rm -f "$ac_file" + + # Try a relative symlink, then a hard link, then a copy. + case $srcdir in + [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;; + *) ac_rel_source=$ac_top_build_prefix$ac_source ;; + esac + ln -s "$ac_rel_source" "$ac_file" 2>/dev/null || + ln "$ac_source" "$ac_file" 2>/dev/null || + cp -p "$ac_source" "$ac_file" || + as_fn_error "cannot link or copy $ac_source to $ac_file" "$LINENO" 5 + fi + ;; + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "Makefile":C) echo "Merging Makefile.sim+Make-common.sim into Makefile ..." + rm -f Makesim1.tmp Makesim2.tmp Makefile + sed -n -e '/^## COMMON_PRE_/,/^## End COMMON_PRE_/ p' Makesim1.tmp + sed -n -e '/^## COMMON_POST_/,/^## End COMMON_POST_/ p' Makesim2.tmp + sed -e '/^## COMMON_PRE_/ r Makesim1.tmp' \ + -e '/^## COMMON_POST_/ r Makesim2.tmp' \ + Makefile + rm -f Makefile.sim Make-common.sim Makesim1.tmp Makesim2.tmp + ;; + "stamp-h":C) echo > stamp-h ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit $? +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + +
configure Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: Makefile.in =================================================================== --- Makefile.in (nonexistent) +++ Makefile.in (revision 816) @@ -0,0 +1,58 @@ +# Makefile template for Configure for the arm sim library. +# Copyright 1995, 1996, 1997, 2002, 2007, 2008, 2009, 2010 +# Free Software Foundation, Inc. +# Written by Cygnus Support. +# +# 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 . + +## COMMON_PRE_CONFIG_FRAG + +SIM_EXTRA_CFLAGS = -DMODET -DNEED_UI_LOOP_HOOK -DSIM_TARGET_SWITCHES + +COPRO=@COPRO@ + +SIM_OBJS = armemu26.o armemu32.o arminit.o armos.o armsupp.o \ + armvirt.o bag.o thumbemu.o wrapper.o sim-load.o $(COPRO) + +## COMMON_POST_CONFIG_FRAG + + +armos.o: armos.c armdefs.h armos.h armfpe.h targ-vals.h + +armcopro.o: armcopro.c armdefs.h +maverick.o: maverick.c armdefs.h +iwmmxt.o: iwmmxt.c iwmmxt.h armdefs.h + +armemu26.o: armemu.c armdefs.h armemu.h + $(CC) -c $(srcdir)/armemu.c -o armemu26.o $(ALL_CFLAGS) + +armemu32.o: armemu.c armdefs.h armemu.h + $(CC) -c $(srcdir)/armemu.c -o armemu32.o -DMODE32 $(ALL_CFLAGS) + +arminit.o: arminit.c armdefs.h armemu.h + +armrdi.o: armrdi.c armdefs.h armemu.h armos.h dbg_cp.h dbg_conf.h dbg_rdi.h \ + dbg_hif.h communicate.h + +armsupp.o: armsupp.c armdefs.h armemu.h + +thumbemu.o: thumbemu.c armdefs.h armemu.h + +bag.o: bag.c bag.h + +wrapper.o: armdefs.h armemu.h dbg_rdi.h \ + $(srcdir)/../common/run-sim.h \ + $(srcdir)/../common/sim-utils.h \ + $(srcdir)/../../include/gdb/sim-arm.h \ + $(srcdir)/../../include/gdb/remote-sim.h Index: arminit.c =================================================================== --- arminit.c (nonexistent) +++ arminit.c (revision 816) @@ -0,0 +1,353 @@ +/* arminit.c -- ARMulator initialization: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +#include "armdefs.h" +#include "armemu.h" +#include "dbg_rdi.h" + +/***************************************************************************\ +* Definitions for the emulator architecture * +\***************************************************************************/ + +void ARMul_EmulateInit (void); +ARMul_State *ARMul_NewState (void); +void ARMul_Reset (ARMul_State * state); +ARMword ARMul_DoCycle (ARMul_State * state); +unsigned ARMul_DoCoPro (ARMul_State * state); +ARMword ARMul_DoProg (ARMul_State * state); +ARMword ARMul_DoInstr (ARMul_State * state); +void ARMul_Abort (ARMul_State * state, ARMword address); + +unsigned ARMul_MultTable[32] = + { 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, + 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16 +}; +ARMword ARMul_ImmedTable[4096]; /* immediate DP LHS values */ +char ARMul_BitList[256]; /* number of bits in a byte table */ + +/***************************************************************************\ +* Call this routine once to set up the emulator's tables. * +\***************************************************************************/ + +void +ARMul_EmulateInit (void) +{ + unsigned long i, j; + + for (i = 0; i < 4096; i++) + { /* the values of 12 bit dp rhs's */ + ARMul_ImmedTable[i] = ROTATER (i & 0xffL, (i >> 7L) & 0x1eL); + } + + for (i = 0; i < 256; ARMul_BitList[i++] = 0); /* how many bits in LSM */ + for (j = 1; j < 256; j <<= 1) + for (i = 0; i < 256; i++) + if ((i & j) > 0) + ARMul_BitList[i]++; + + for (i = 0; i < 256; i++) + ARMul_BitList[i] *= 4; /* you always need 4 times these values */ + +} + +/***************************************************************************\ +* Returns a new instantiation of the ARMulator's state * +\***************************************************************************/ + +ARMul_State * +ARMul_NewState (void) +{ + ARMul_State *state; + unsigned i, j; + + state = (ARMul_State *) malloc (sizeof (ARMul_State)); + memset (state, 0, sizeof (ARMul_State)); + + state->Emulate = RUN; + for (i = 0; i < 16; i++) + { + state->Reg[i] = 0; + for (j = 0; j < 7; j++) + state->RegBank[j][i] = 0; + } + for (i = 0; i < 7; i++) + state->Spsr[i] = 0; + + /* state->Mode = USER26MODE; */ + state->Mode = USER32MODE; + + state->CallDebug = FALSE; + state->Debug = FALSE; + state->VectorCatch = 0; + state->Aborted = FALSE; + state->Reseted = FALSE; + state->Inted = 3; + state->LastInted = 3; + + state->MemDataPtr = NULL; + state->MemInPtr = NULL; + state->MemOutPtr = NULL; + state->MemSparePtr = NULL; + state->MemSize = 0; + + state->OSptr = NULL; + state->CommandLine = NULL; + + state->CP14R0_CCD = -1; + state->LastTime = 0; + + state->EventSet = 0; + state->Now = 0; + state->EventPtr = (struct EventNode **) malloc ((unsigned) EVENTLISTSIZE * + sizeof (struct EventNode + *)); + for (i = 0; i < EVENTLISTSIZE; i++) + *(state->EventPtr + i) = NULL; + + state->prog32Sig = HIGH; + state->data32Sig = HIGH; + + state->lateabtSig = LOW; + state->bigendSig = LOW; + + state->is_v4 = LOW; + state->is_v5 = LOW; + state->is_v5e = LOW; + state->is_XScale = LOW; + state->is_iWMMXt = LOW; + state->is_v6 = LOW; + + ARMul_Reset (state); + + return state; +} + +/***************************************************************************\ + Call this routine to set ARMulator to model certain processor properities +\***************************************************************************/ + +void +ARMul_SelectProcessor (ARMul_State * state, unsigned properties) +{ + if (properties & ARM_Fix26_Prop) + { + state->prog32Sig = LOW; + state->data32Sig = LOW; + } + else + { + state->prog32Sig = HIGH; + state->data32Sig = HIGH; + } + + state->lateabtSig = LOW; + + state->is_v4 = (properties & (ARM_v4_Prop | ARM_v5_Prop)) ? HIGH : LOW; + state->is_v5 = (properties & ARM_v5_Prop) ? HIGH : LOW; + state->is_v5e = (properties & ARM_v5e_Prop) ? HIGH : LOW; + state->is_XScale = (properties & ARM_XScale_Prop) ? HIGH : LOW; + state->is_iWMMXt = (properties & ARM_iWMMXt_Prop) ? HIGH : LOW; + state->is_ep9312 = (properties & ARM_ep9312_Prop) ? HIGH : LOW; + state->is_v6 = (properties & ARM_v6_Prop) ? HIGH : LOW; + + /* Only initialse the coprocessor support once we + know what kind of chip we are dealing with. */ + ARMul_CoProInit (state); +} + +/***************************************************************************\ +* Call this routine to set up the initial machine state (or perform a RESET * +\***************************************************************************/ + +void +ARMul_Reset (ARMul_State * state) +{ + state->NextInstr = 0; + + if (state->prog32Sig) + { + state->Reg[15] = 0; + state->Cpsr = INTBITS | SVC32MODE; + state->Mode = SVC32MODE; + } + else + { + state->Reg[15] = R15INTBITS | SVC26MODE; + state->Cpsr = INTBITS | SVC26MODE; + state->Mode = SVC26MODE; + } + + ARMul_CPSRAltered (state); + state->Bank = SVCBANK; + + FLUSHPIPE; + + state->EndCondition = 0; + state->ErrorCode = 0; + + state->Exception = FALSE; + state->NresetSig = HIGH; + state->NfiqSig = HIGH; + state->NirqSig = HIGH; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + state->abortSig = LOW; + state->AbortAddr = 1; + + state->NumInstrs = 0; + state->NumNcycles = 0; + state->NumScycles = 0; + state->NumIcycles = 0; + state->NumCcycles = 0; + state->NumFcycles = 0; +#ifdef ASIM + (void) ARMul_MemoryInit (); + ARMul_OSInit (state); +#endif +} + + +/***************************************************************************\ +* Emulate the execution of an entire program. Start the correct emulator * +* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the * +* address of the last instruction that is executed. * +\***************************************************************************/ + +ARMword +ARMul_DoProg (ARMul_State * state) +{ + ARMword pc = 0; + + state->Emulate = RUN; + while (state->Emulate != STOP) + { + state->Emulate = RUN; + if (state->prog32Sig && ARMul_MODE32BIT) + pc = ARMul_Emulate32 (state); + else + pc = ARMul_Emulate26 (state); + } + return (pc); +} + +/***************************************************************************\ +* Emulate the execution of one instruction. Start the correct emulator * +* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the * +* address of the instruction that is executed. * +\***************************************************************************/ + +ARMword +ARMul_DoInstr (ARMul_State * state) +{ + ARMword pc = 0; + + state->Emulate = ONCE; + if (state->prog32Sig && ARMul_MODE32BIT) + pc = ARMul_Emulate32 (state); + else + pc = ARMul_Emulate26 (state); + + return (pc); +} + +/***************************************************************************\ +* This routine causes an Abort to occur, including selecting the correct * +* mode, register bank, and the saving of registers. Call with the * +* appropriate vector's memory address (0,4,8 ....) * +\***************************************************************************/ + +void +ARMul_Abort (ARMul_State * state, ARMword vector) +{ + ARMword temp; + int isize = INSN_SIZE; + int esize = (TFLAG ? 0 : 4); + int e2size = (TFLAG ? -4 : 0); + + state->Aborted = FALSE; + + if (ARMul_OSException (state, vector, ARMul_GetPC (state))) + return; + + if (state->prog32Sig) + if (ARMul_MODE26BIT) + temp = R15PC; + else + temp = state->Reg[15]; + else + temp = R15PC | ECC | ER15INT | EMODE; + + switch (vector) + { + case ARMul_ResetV: /* RESET */ + SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE, 0); + break; + case ARMul_UndefinedInstrV: /* Undefined Instruction */ + SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE, isize); + break; + case ARMul_SWIV: /* Software Interrupt */ + SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE, isize); + break; + case ARMul_PrefetchAbortV: /* Prefetch Abort */ + state->AbortAddr = 1; + SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, esize); + break; + case ARMul_DataAbortV: /* Data Abort */ + SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE, e2size); + break; + case ARMul_AddrExceptnV: /* Address Exception */ + SETABORT (IBIT, SVC26MODE, isize); + break; + case ARMul_IRQV: /* IRQ */ + if ( ! state->is_XScale + || ! state->CPRead[13] (state, 0, & temp) + || (temp & ARMul_CP13_R0_IRQ)) + SETABORT (IBIT, state->prog32Sig ? IRQ32MODE : IRQ26MODE, esize); + break; + case ARMul_FIQV: /* FIQ */ + if ( ! state->is_XScale + || ! state->CPRead[13] (state, 0, & temp) + || (temp & ARMul_CP13_R0_FIQ)) + SETABORT (INTBITS, state->prog32Sig ? FIQ32MODE : FIQ26MODE, esize); + break; + } + if (ARMul_MODE32BIT) + ARMul_SetR15 (state, vector); + else + ARMul_SetR15 (state, R15CCINTMODE | vector); + + if (ARMul_ReadWord (state, ARMul_GetPC (state)) == 0) + { + /* No vector has been installed. Rather than simulating whatever + random bits might happen to be at address 0x20 onwards we elect + to stop. */ + switch (vector) + { + case ARMul_ResetV: state->EndCondition = RDIError_Reset; break; + case ARMul_UndefinedInstrV: state->EndCondition = RDIError_UndefinedInstruction; break; + case ARMul_SWIV: state->EndCondition = RDIError_SoftwareInterrupt; break; + case ARMul_PrefetchAbortV: state->EndCondition = RDIError_PrefetchAbort; break; + case ARMul_DataAbortV: state->EndCondition = RDIError_DataAbort; break; + case ARMul_AddrExceptnV: state->EndCondition = RDIError_AddressException; break; + case ARMul_IRQV: state->EndCondition = RDIError_IRQ; break; + case ARMul_FIQV: state->EndCondition = RDIError_FIQ; break; + default: break; + } + state->Emulate = FALSE; + } +}
arminit.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: communicate.c =================================================================== --- communicate.c (nonexistent) +++ communicate.c (revision 816) @@ -0,0 +1,255 @@ +/* communicate.c -- ARMulator RDP comms code: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/**************************************************************************/ +/* Functions to read and write characters or groups of characters */ +/* down sockets or pipes. Those that return a value return -1 on failure */ +/* and 0 on success. */ +/**************************************************************************/ + +#include +#include +#include +#include + +#include "armdefs.h" + +/* The socket to the debugger */ +int debugsock; + +/* The maximum number of file descriptors */ +extern int nfds; + +/* The socket handle */ +extern int sockethandle; + +/* Read and Write routines down a pipe or socket */ + +/****************************************************************/ +/* Read an individual character. */ +/* All other read functions rely on this one. */ +/* It waits 15 seconds until there is a character available: if */ +/* no character is available, then it timeouts and returns -1. */ +/****************************************************************/ +int +MYread_char (int sock, unsigned char *c) +{ + int i; + fd_set readfds; + struct timeval timeout = { 15, 0 }; + struct sockaddr_in isa; + +retry: + + FD_ZERO (&readfds); + FD_SET (sock, &readfds); + + i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout); + + if (i < 0) + { + perror ("select"); + exit (1); + } + + if (!i) + { + fprintf (stderr, "read: Timeout\n"); + return -1; + } + + if ((i = read (sock, c, 1)) < 1) + { + if (!i && sock == debugsock) + { + fprintf (stderr, "Connection with debugger severed.\n"); + /* This shouldn't be necessary for a detached armulator, but + the armulator cannot be cold started a second time, so + this is probably preferable to locking up. */ + return -1; + fprintf (stderr, "Waiting for connection from debugger..."); + debugsock = accept (sockethandle, &isa, &i); + if (debugsock < 0) + { /* Now we are in serious trouble... */ + perror ("accept"); + return -1; + } + fprintf (stderr, " done.\nConnection Established.\n"); + sock = debugsock; + goto retry; + } + perror ("read"); + return -1; + } + +#ifdef DEBUG + if (sock == debugsock) + fprintf (stderr, "<%02x ", *c); +#endif + + return 0; +} + +/****************************************************************/ +/* Read an individual character. */ +/* It waits until there is a character available. Returns -1 if */ +/* an error occurs. */ +/****************************************************************/ +int +MYread_charwait (int sock, unsigned char *c) +{ + int i; + fd_set readfds; + struct sockaddr_in isa; + +retry: + + FD_ZERO (&readfds); + FD_SET (sock, &readfds); + + i = select (nfds, &readfds, + (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); + + if (i < 0) + { + perror ("select"); + exit (-1); + } + + if ((i = read (sock, c, 1)) < 1) + { + if (!i && sock == debugsock) + { + fprintf (stderr, "Connection with debugger severed.\n"); + return -1; + fprintf (stderr, "Waiting for connection from debugger..."); + debugsock = accept (sockethandle, &isa, &i); + if (debugsock < 0) + { /* Now we are in serious trouble... */ + perror ("accept"); + return -1; + } + fprintf (stderr, " done.\nConnection Established.\n"); + sock = debugsock; + goto retry; + } + perror ("read"); + return -1; + } + +#ifdef DEBUG + if (sock == debugsock) + fprintf (stderr, "<%02x ", *c); +#endif + + return 0; +} + +void +MYwrite_char (int sock, unsigned char c) +{ + + if (write (sock, &c, 1) < 1) + perror ("write"); +#ifdef DEBUG + if (sock == debugsock) + fprintf (stderr, ">%02x ", c); +#endif +} + +int +MYread_word (int sock, ARMword * here) +{ + unsigned char a, b, c, d; + + if (MYread_char (sock, &a) < 0) + return -1; + if (MYread_char (sock, &b) < 0) + return -1; + if (MYread_char (sock, &c) < 0) + return -1; + if (MYread_char (sock, &d) < 0) + return -1; + *here = a | b << 8 | c << 16 | d << 24; + return 0; +} + +void +MYwrite_word (int sock, ARMword i) +{ + MYwrite_char (sock, i & 0xff); + MYwrite_char (sock, (i & 0xff00) >> 8); + MYwrite_char (sock, (i & 0xff0000) >> 16); + MYwrite_char (sock, (i & 0xff000000) >> 24); +} + +void +MYwrite_string (int sock, char *s) +{ + int i; + for (i = 0; MYwrite_char (sock, s[i]), s[i]; i++); +} + +int +MYread_FPword (int sock, char *putinhere) +{ + int i; + for (i = 0; i < 16; i++) + if (MYread_char (sock, &putinhere[i]) < 0) + return -1; + return 0; +} + +void +MYwrite_FPword (int sock, char *fromhere) +{ + int i; + for (i = 0; i < 16; i++) + MYwrite_char (sock, fromhere[i]); +} + +/* Takes n bytes from source and those n bytes */ +/* down to dest */ +int +passon (int source, int dest, int n) +{ + char *p; + int i; + + p = (char *) malloc (n); + if (!p) + { + perror ("Out of memory\n"); + exit (1); + } + if (n) + { + for (i = 0; i < n; i++) + if (MYread_char (source, &p[i]) < 0) + return -1; + +#ifdef DEBUG + if (dest == debugsock) + for (i = 0; i < n; i++) + fprintf (stderr, ")%02x ", (unsigned char) p[i]); +#endif + + write (dest, p, n); + } + free (p); + return 0; +}
communicate.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: dbg_conf.h =================================================================== --- dbg_conf.h (nonexistent) +++ dbg_conf.h (revision 816) @@ -0,0 +1,50 @@ +/* dbg_conf.h -- ARMulator debug interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef Dbg_Conf__h + +#define Dbg_Conf__h + +typedef struct Dbg_ConfigBlock +{ + int bytesex; + long memorysize; + int serialport; /*) remote connection parameters */ + int seriallinespeed; /*) (serial connection) */ + int parallelport; /*) ditto */ + int parallellinespeed; /*) (parallel connection) */ + int processor; /* processor the armulator is to emulate (eg ARM60) */ + int rditype; /* armulator / remote processor */ + int drivertype; /* parallel / serial / etc */ + char const *configtoload; + int flags; +} +Dbg_ConfigBlock; + +#define Dbg_ConfigFlag_Reset 1 + +typedef struct Dbg_HostosInterface Dbg_HostosInterface; +/* This structure allows access by the (host-independent) C-library support + module of armulator or pisd (armos.c) to host-dependent functions for + which there is no host-independent interface. Its contents are unknown + to the debugger toolbox. + The assumption is that, in a windowed system, fputc(stderr) for example + may not achieve the desired effect of the character appearing in some + window. + */ + +#endif
dbg_conf.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: communicate.h =================================================================== --- communicate.h (nonexistent) +++ communicate.h (revision 816) @@ -0,0 +1,36 @@ +/* communicate.h -- ARMulator comms support defns: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +int MYread_char (int sock, unsigned char *c); +void MYwrite_char (int sock, unsigned char c); +int MYread_word (int sock, ARMword * here); +void MYwrite_word (int sock, ARMword i); +void MYwrite_string (int sock, char *s); +int MYread_FPword (int sock, char *putinhere); +void MYwrite_FPword (int sock, char *fromhere); +int passon (int source, int dest, int n); + +int wait_for_osreply (ARMword * reply); /* from kid.c */ + +#define OS_SendNothing 0x0 +#define OS_SendChar 0x1 +#define OS_SendWord 0x2 +#define OS_SendString 0x3 + +/* The pipes between the two processes */ +extern int mumkid[2]; +extern int kidmum[2];
communicate.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: tconfig.in =================================================================== --- tconfig.in (nonexistent) +++ tconfig.in (revision 816) @@ -0,0 +1,17 @@ +/* ARM target configuration file. */ + +/* Define this if the simulator supports profiling. + See the mips simulator for an example. + This enables the `-p foo' and `-s bar' options. + The target is required to provide sim_set_profile{,_size}. */ +/* #define SIM_HAVE_PROFILE */ + +/* Define this if the simulator uses an instruction cache. + See the h8/300 simulator for an example. + This enables the `-c size' option to set the size of the cache. + The target is required to provide sim_set_simcache_size. */ +/* #define SIM_HAVE_SIMCACHE */ + +/* Define this if the target cpu is bi-endian + and the simulator supports it. */ +#define SIM_HAVE_BIENDIAN Index: armrdi.c =================================================================== --- armrdi.c (nonexistent) +++ armrdi.c (revision 816) @@ -0,0 +1,1247 @@ +/* armrdi.c -- ARMulator RDI interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include +#include +#include "armdefs.h" +#include "armemu.h" +#include "armos.h" +#include "dbg_cp.h" +#include "dbg_conf.h" +#include "dbg_rdi.h" +#include "dbg_hif.h" +#include "communicate.h" + +/***************************************************************************\ +* Declarations * +\***************************************************************************/ + +#define Watch_AnyRead (RDIWatch_ByteRead+RDIWatch_HalfRead+RDIWatch_WordRead) +#define Watch_AnyWrite (RDIWatch_ByteWrite+RDIWatch_HalfWrite+RDIWatch_WordWrite) + +static unsigned FPRegsAddr; /* last known address of FPE regs */ +#define FPESTART 0x2000L +#define FPEEND 0x8000L + +#define IGNORE(d) (d = d) +#ifdef RDI_VERBOSE +#define TracePrint(s) \ + if (rdi_log & 1) ARMul_DebugPrint s +#else +#define TracePrint(s) +#endif + +static ARMul_State *state = NULL; +static unsigned BreaksSet; /* The number of breakpoints set */ + +static int rdi_log = 0; /* debugging ? */ + +#define LOWEST_RDI_LEVEL 0 +#define HIGHEST_RDI_LEVEL 1 +static int MYrdi_level = LOWEST_RDI_LEVEL; + +typedef struct BreakNode BreakNode; +typedef struct WatchNode WatchNode; + +struct BreakNode +{ /* A breakpoint list node */ + BreakNode *next; + ARMword address; /* The address of this breakpoint */ + unsigned type; /* The type of comparison */ + ARMword bound; /* The other address for a range */ + ARMword inst; +}; + +struct WatchNode +{ /* A watchpoint list node */ + WatchNode *next; + ARMword address; /* The address of this watchpoint */ + unsigned type; /* The type of comparison */ + unsigned datatype; /* The type of access to watch for */ + ARMword bound; /* The other address for a range */ +}; + +BreakNode *BreakList = NULL; +WatchNode *WatchList = NULL; + +void +ARMul_DebugPrint_i (const Dbg_HostosInterface * hostif, const char *format, + ...) +{ + va_list ap; + va_start (ap, format); + hostif->dbgprint (hostif->dbgarg, format, ap); + va_end (ap); +} + +void +ARMul_DebugPrint (ARMul_State * state, const char *format, ...) +{ + va_list ap; + va_start (ap, format); + if (!(rdi_log & 8)) + state->hostif->dbgprint (state->hostif->dbgarg, format, ap); + va_end (ap); +} + +#define CONSOLE_PRINT_MAX_LEN 128 + +void +ARMul_ConsolePrint (ARMul_State * state, const char *format, ...) +{ + va_list ap; + int ch; + char *str, buf[CONSOLE_PRINT_MAX_LEN]; + int i, j; + ARMword junk; + + va_start (ap, format); + vsprintf (buf, format, ap); + + for (i = 0; buf[i]; i++); /* The string is i chars long */ + + str = buf; + while (i >= 32) + { + MYwrite_char (kidmum[1], RDP_OSOp); + MYwrite_word (kidmum[1], SWI_Write0); + MYwrite_char (kidmum[1], OS_SendString); + MYwrite_char (kidmum[1], 32); /* Send string 32bytes at a time */ + for (j = 0; j < 32; j++, str++) + MYwrite_char (kidmum[1], *str); + wait_for_osreply (&junk); + i -= 32; + } + + if (i > 0) + { + MYwrite_char (kidmum[1], RDP_OSOp); + MYwrite_word (kidmum[1], SWI_Write0); + MYwrite_char (kidmum[1], OS_SendString); + MYwrite_char (kidmum[1], (unsigned char) i); /* Send remainder of string */ + for (j = 0; j < i; j++, str++) + MYwrite_char (kidmum[1], *str); + wait_for_osreply (&junk); + } + + va_end (ap); + return; + +/* str = buf; */ +/* while ((ch=*str++) != 0) */ +/* state->hostif->writec(state->hostif->hostosarg, ch); */ +} + +void +ARMul_DebugPause (ARMul_State * state) +{ + if (!(rdi_log & 8)) + state->hostif->dbgpause (state->hostif->dbgarg); +} + +/***************************************************************************\ +* RDI_open * +\***************************************************************************/ + +static void +InitFail (int exitcode, char const *which) +{ + ARMul_ConsolePrint (state, "%s interface failed to initialise. Exiting\n", + which); + exit (exitcode); +} + +static void +RDIInit (unsigned type) +{ + if (type == 0) + { /* cold start */ + state->CallDebug = state->MemReadDebug = state->MemWriteDebug = 0; + BreaksSet = 0; + } +} + +#define UNKNOWNPROC 0 + +typedef struct +{ + char name[16]; + unsigned properties; +} +Processor; + +Processor const p_arm2 = { "ARM2", ARM_Fix26_Prop }; +Processor const p_arm2as = { "ARM2AS", ARM_Fix26_Prop }; +Processor const p_arm61 = { "ARM61", ARM_Fix26_Prop }; +Processor const p_arm3 = { "ARM3", ARM_Fix26_Prop }; +Processor const p_arm6 = { "ARM6", ARM_Lock_Prop }; +Processor const p_arm60 = { "ARM60", ARM_Lock_Prop }; +Processor const p_arm600 = { "ARM600", ARM_Lock_Prop }; +Processor const p_arm610 = { "ARM610", ARM_Lock_Prop }; +Processor const p_arm620 = { "ARM620", ARM_Lock_Prop }; +Processor const p_unknown = { "", 0 }; + +Processor const *const processors[] = +{ + &p_arm6, /* default: must come first */ + &p_arm2, + &p_arm2as, + &p_arm61, + &p_arm3, + &p_arm60, + &p_arm600, + &p_arm610, + &p_arm620, + &p_unknown +}; + +typedef struct ProcessorConfig ProcessorConfig; +struct ProcessorConfig +{ + long id[2]; + ProcessorConfig const *self; + long count; + Processor const *const *processors; +}; + +ProcessorConfig const processorconfig = { + {((((((long) 'x' << 8) | ' ') << 8) | 'c') << 8) | 'p', + ((((((long) 'u' << 8) | 's') << 8) | ' ') << 8) | 'x'}, + &processorconfig, + 16, + processors +}; + +static int +RDI_open (unsigned type, const Dbg_ConfigBlock * config, + const Dbg_HostosInterface * hostif, struct Dbg_MCState *dbg_state) +/* Initialise everything */ +{ + int virgin = (state == NULL); + IGNORE (dbg_state); + +#ifdef RDI_VERBOSE + if (rdi_log & 1) + { + if (virgin) + ARMul_DebugPrint_i (hostif, "RDI_open: type = %d\n", type); + else + ARMul_DebugPrint (state, "RDI_open: type = %d\n", type); + } +#endif + + if (type & 1) + { /* Warm start */ + ARMul_Reset (state); + RDIInit (1); + } + else + { + if (virgin) + { + ARMul_EmulateInit (); + state = ARMul_NewState (); + state->hostif = hostif; + { + int req = config->processor; + unsigned processor = processors[req]->val; + ARMul_SelectProcessor (state, processor); + ARMul_Reset (state); + ARMul_ConsolePrint (state, "ARMulator V1.50, %s", + processors[req]->name); + } + if (ARMul_MemoryInit (state, config->memorysize) == FALSE) + InitFail (1, "Memory"); + if (config->bytesex != RDISex_DontCare) + state->bigendSig = config->bytesex; + if (ARMul_CoProInit (state) == FALSE) + InitFail (2, "Co-Processor"); + if (ARMul_OSInit (state) == FALSE) + InitFail (3, "Operating System"); + } + ARMul_Reset (state); + RDIInit (0); + } + if (type & 2) + { /* Reset the comms link */ + /* what comms link ? */ + } + if (virgin && (type & 1) == 0) /* Cold start */ + ARMul_ConsolePrint (state, ", %s endian.\n", + state->bigendSig ? "Big" : "Little"); + + if (config->bytesex == RDISex_DontCare) + return (state->bigendSig ? RDIError_BigEndian : RDIError_LittleEndian); + else + return (RDIError_NoError); +} + +/***************************************************************************\ +* RDI_close * +\***************************************************************************/ + +static int +RDI_close (void) +{ + TracePrint ((state, "RDI_close\n")); + ARMul_OSExit (state); + ARMul_CoProExit (state); + ARMul_MemoryExit (state); + return (RDIError_NoError); +} + +/***************************************************************************\ +* RDI_read * +\***************************************************************************/ + +static int +RDI_read (ARMword source, void *dest, unsigned *nbytes) +{ + unsigned i; + char *memptr = (char *) dest; + + TracePrint ((state, "RDI_read: source=%.8lx dest=%p nbytes=%.8x\n", + source, dest, *nbytes)); + + for (i = 0; i < *nbytes; i++) + *memptr++ = (char) ARMul_ReadByte (state, source++); + if (state->abortSig) + { + state->abortSig = LOW; + return (RDIError_DataAbort); + } + return (RDIError_NoError); +} + +/***************************************************************************\ +* RDI_write * +\***************************************************************************/ + +static int +RDI_write (const void *source, ARMword dest, unsigned *nbytes) +{ + unsigned i; + char *memptr = (char *) source; + + TracePrint ((state, "RDI_write: source=%p dest=%.8lx nbytes=%.8x\n", + source, dest, *nbytes)); + + for (i = 0; i < *nbytes; i++) + ARMul_WriteByte (state, (ARMword) dest++, (ARMword) * memptr++); + + if (state->abortSig) + { + state->abortSig = LOW; + return (RDIError_DataAbort); + } + return (RDIError_NoError); +} + +/***************************************************************************\ +* RDI_CPUread * +\***************************************************************************/ + +static int +RDI_CPUread (unsigned mode, unsigned long mask, ARMword buffer[]) +{ + unsigned i, upto; + + if (mode == RDIMode_Curr) + mode = (unsigned) (ARMul_GetCPSR (state) & MODEBITS); + + for (upto = 0, i = 0; i < 15; i++) + if (mask & (1L << i)) + { + buffer[upto++] = ARMul_GetReg (state, mode, i); + } + + if (mask & RDIReg_R15) + { + buffer[upto++] = ARMul_GetR15 (state); + } + + if (mask & RDIReg_PC) + { + buffer[upto++] = ARMul_GetPC (state); + } + + if (mask & RDIReg_CPSR) + buffer[upto++] = ARMul_GetCPSR (state); + + if (mask & RDIReg_SPSR) + buffer[upto++] = ARMul_GetSPSR (state, mode); + + TracePrint ((state, "RDI_CPUread: mode=%.8x mask=%.8lx", mode, mask)); +#ifdef RDI_VERBOSE + if (rdi_log & 1) + { + for (upto = 0, i = 0; i <= 20; i++) + if (mask & (1L << i)) + { + ARMul_DebugPrint (state, "%c%.8lx", upto % 4 == 0 ? '\n' : ' ', + buffer[upto]); + upto++; + } + ARMul_DebugPrint (state, "\n"); + } +#endif + + return (RDIError_NoError); +} + +/***************************************************************************\ +* RDI_CPUwrite * +\***************************************************************************/ + +static int +RDI_CPUwrite (unsigned mode, unsigned long mask, ARMword const buffer[]) +{ + int i, upto; + + + TracePrint ((state, "RDI_CPUwrite: mode=%.8x mask=%.8lx", mode, mask)); +#ifdef RDI_VERBOSE + if (rdi_log & 1) + { + for (upto = 0, i = 0; i <= 20; i++) + if (mask & (1L << i)) + { + ARMul_DebugPrint (state, "%c%.8lx", upto % 4 == 0 ? '\n' : ' ', + buffer[upto]); + upto++; + } + ARMul_DebugPrint (state, "\n"); + } +#endif + + if (mode == RDIMode_Curr) + mode = (unsigned) (ARMul_GetCPSR (state) & MODEBITS); + + for (upto = 0, i = 0; i < 15; i++) + if (mask & (1L << i)) + ARMul_SetReg (state, mode, i, buffer[upto++]); + + if (mask & RDIReg_R15) + ARMul_SetR15 (state, buffer[upto++]); + + if (mask & RDIReg_PC) + { + + ARMul_SetPC (state, buffer[upto++]); + } + if (mask & RDIReg_CPSR) + ARMul_SetCPSR (state, buffer[upto++]); + + if (mask & RDIReg_SPSR) + ARMul_SetSPSR (state, mode, buffer[upto++]); + + return (RDIError_NoError); +} + +/***************************************************************************\ +* RDI_CPread * +\***************************************************************************/ + +static int +RDI_CPread (unsigned CPnum, unsigned long mask, ARMword buffer[]) +{ + ARMword fpregsaddr, word[4]; + + unsigned r, w; + unsigned upto; + + if (CPnum != 1 && CPnum != 2) + { + unsigned char const *rmap = state->CPRegWords[CPnum]; + if (rmap == NULL) + return (RDIError_UnknownCoPro); + for (upto = 0, r = 0; r < rmap[-1]; r++) + if (mask & (1L << r)) + { + (void) state->CPRead[CPnum] (state, r, &buffer[upto]); + upto += rmap[r]; + } + TracePrint ((state, "RDI_CPread: CPnum=%d mask=%.8lx", CPnum, mask)); +#ifdef RDI_VERBOSE + if (rdi_log & 1) + { + w = 0; + for (upto = 0, r = 0; r < rmap[-1]; r++) + if (mask & (1L << r)) + { + int words = rmap[r]; + ARMul_DebugPrint (state, "%c%2d", + (w >= 4 ? (w = 0, '\n') : ' '), r); + while (--words >= 0) + { + ARMul_DebugPrint (state, " %.8lx", buffer[upto++]); + w++; + } + } + ARMul_DebugPrint (state, "\n"); + } +#endif + return RDIError_NoError; + } + +#ifdef NOFPE + return RDIError_UnknownCoPro; + +#else + if (FPRegsAddr == 0) + { + fpregsaddr = ARMul_ReadWord (state, 4L); + if ((fpregsaddr & 0xff800000) != 0xea000000) /* Must be a forward branch */ + return RDIError_UnknownCoPro; + fpregsaddr = ((fpregsaddr & 0xffffff) << 2) + 8; /* address in __fp_decode - 4 */ + if ((fpregsaddr < FPESTART) || (fpregsaddr >= FPEEND)) + return RDIError_UnknownCoPro; + fpregsaddr = ARMul_ReadWord (state, fpregsaddr); /* pointer to fp registers */ + FPRegsAddr = fpregsaddr; + } + else + fpregsaddr = FPRegsAddr; + + if (fpregsaddr == 0) + return RDIError_UnknownCoPro; + for (upto = 0, r = 0; r < 8; r++) + if (mask & (1L << r)) + { + for (w = 0; w < 4; w++) + word[w] = + ARMul_ReadWord (state, + fpregsaddr + (ARMword) r * 16 + (ARMword) w * 4); + switch ((int) (word[3] >> 29)) + { + case 0: + case 2: + case 4: + case 6: /* its unpacked, convert to extended */ + buffer[upto++] = 2; /* mark as extended */ + buffer[upto++] = (word[3] & 0x7fff) | (word[0] & 0x80000000); /* exp and sign */ + buffer[upto++] = word[1]; /* mantissa 1 */ + buffer[upto++] = word[2]; /* mantissa 2 */ + break; + case 1: /* packed single */ + buffer[upto++] = 0; /* mark as single */ + buffer[upto++] = word[0]; /* sign, exp and mantissa */ + buffer[upto++] = word[1]; /* padding */ + buffer[upto++] = word[2]; /* padding */ + break; + case 3: /* packed double */ + buffer[upto++] = 1; /* mark as double */ + buffer[upto++] = word[0]; /* sign, exp and mantissa1 */ + buffer[upto++] = word[1]; /* mantissa 2 */ + buffer[upto++] = word[2]; /* padding */ + break; + case 5: /* packed extended */ + buffer[upto++] = 2; /* mark as extended */ + buffer[upto++] = word[0]; /* sign and exp */ + buffer[upto++] = word[1]; /* mantissa 1 */ + buffer[upto++] = word[2]; /* mantissa 2 */ + break; + case 7: /* packed decimal */ + buffer[upto++] = 3; /* mark as packed decimal */ + buffer[upto++] = word[0]; /* sign, exp and mantissa1 */ + buffer[upto++] = word[1]; /* mantissa 2 */ + buffer[upto++] = word[2]; /* mantissa 3 */ + break; + } + } + if (mask & (1L << r)) + buffer[upto++] = ARMul_ReadWord (state, fpregsaddr + 128); /* fpsr */ + if (mask & (1L << (r + 1))) + buffer[upto++] = 0; /* fpcr */ + + TracePrint ((state, "RDI_CPread: CPnum=%d mask=%.8lx\n", CPnum, mask)); +#ifdef RDI_VERBOSE + if (rdi_log & 1) + { + for (upto = 0, r = 0; r < 9; r++) + if (mask & (1L << r)) + { + if (r != 8) + { + ARMul_DebugPrint (state, "%08lx ", buffer[upto++]); + ARMul_DebugPrint (state, "%08lx ", buffer[upto++]); + ARMul_DebugPrint (state, "%08lx ", buffer[upto++]); + } + ARMul_DebugPrint (state, "%08lx\n", buffer[upto++]); + } + ARMul_DebugPrint (state, "\n"); + } +#endif + return (RDIError_NoError); +#endif /* NOFPE */ +} + +/***************************************************************************\ +* RDI_CPwrite * +\***************************************************************************/ + +static int +RDI_CPwrite (unsigned CPnum, unsigned long mask, ARMword const buffer[]) +{ + unsigned r; + unsigned upto; + ARMword fpregsaddr; + + if (CPnum != 1 && CPnum != 2) + { + unsigned char const *rmap = state->CPRegWords[CPnum]; + if (rmap == NULL) + return (RDIError_UnknownCoPro); + TracePrint ((state, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum, mask)); +#ifdef RDI_VERBOSE + if (rdi_log & 1) + { + int w = 0; + for (upto = 0, r = 0; r < rmap[-1]; r++) + if (mask & (1L << r)) + { + int words = rmap[r]; + ARMul_DebugPrint (state, "%c%2d", + (w >= 4 ? (w = 0, '\n') : ' '), r); + while (--words >= 0) + { + ARMul_DebugPrint (state, " %.8lx", buffer[upto++]); + w++; + } + } + ARMul_DebugPrint (state, "\n"); + } +#endif + for (upto = 0, r = 0; r < rmap[-1]; r++) + if (mask & (1L << r)) + { + (void) state->CPWrite[CPnum] (state, r, &buffer[upto]); + upto += rmap[r]; + } + return RDIError_NoError; + } + +#ifdef NOFPE + return RDIError_UnknownCoPro; + +#else + TracePrint ((state, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum, mask)); +#ifdef RDI_VERBOSE + if (rdi_log & 1) + { + for (upto = 0, r = 0; r < 9; r++) + if (mask & (1L << r)) + { + if (r != 8) + { + ARMul_DebugPrint (state, "%08lx ", buffer[upto++]); + ARMul_DebugPrint (state, "%08lx ", buffer[upto++]); + ARMul_DebugPrint (state, "%08lx ", buffer[upto++]); + } + ARMul_DebugPrint (state, "%08lx\n", buffer[upto++]); + } + ARMul_DebugPrint (state, "\n"); + } +#endif + + if (FPRegsAddr == 0) + { + fpregsaddr = ARMul_ReadWord (state, 4L); + if ((fpregsaddr & 0xff800000) != 0xea000000) /* Must be a forward branch */ + return RDIError_UnknownCoPro; + fpregsaddr = ((fpregsaddr & 0xffffff) << 2) + 8; /* address in __fp_decode - 4 */ + if ((fpregsaddr < FPESTART) || (fpregsaddr >= FPEEND)) + return RDIError_UnknownCoPro; + fpregsaddr = ARMul_ReadWord (state, fpregsaddr); /* pointer to fp registers */ + FPRegsAddr = fpregsaddr; + } + else + fpregsaddr = FPRegsAddr; + + if (fpregsaddr == 0) + return RDIError_UnknownCoPro; + for (upto = 0, r = 0; r < 8; r++) + if (mask & (1L << r)) + { + ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16, + buffer[upto + 1]); + ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16 + 4, + buffer[upto + 2]); + ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16 + 8, + buffer[upto + 3]); + ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16 + 12, + (buffer[upto] * 2 + 1) << 29); /* mark type */ + upto += 4; + } + if (mask & (1L << r)) + ARMul_WriteWord (state, fpregsaddr + 128, buffer[upto++]); /* fpsr */ + return (RDIError_NoError); +#endif /* NOFPE */ +} + +static void +deletebreaknode (BreakNode ** prevp) +{ + BreakNode *p = *prevp; + *prevp = p->next; + ARMul_WriteWord (state, p->address, p->inst); + free ((char *) p); + BreaksSet--; + state->CallDebug--; +} + +static int +removebreak (ARMword address, unsigned type) +{ + BreakNode *p, **prevp = &BreakList; + for (; (p = *prevp) != NULL; prevp = &p->next) + if (p->address == address && p->type == type) + { + deletebreaknode (prevp); + return TRUE; + } + return FALSE; +} + +/* This routine installs a breakpoint into the breakpoint table */ + +static BreakNode * +installbreak (ARMword address, unsigned type, ARMword bound) +{ + BreakNode *p = (BreakNode *) malloc (sizeof (BreakNode)); + p->next = BreakList; + BreakList = p; + p->address = address; + p->type = type; + p->bound = bound; + p->inst = ARMul_ReadWord (state, address); + ARMul_WriteWord (state, address, 0xee000000L); + return p; +} + +/***************************************************************************\ +* RDI_setbreak * +\***************************************************************************/ + +static int +RDI_setbreak (ARMword address, unsigned type, ARMword bound, + PointHandle * handle) +{ + BreakNode *p; + TracePrint ((state, "RDI_setbreak: address=%.8lx type=%d bound=%.8lx\n", + address, type, bound)); + + removebreak (address, type); + p = installbreak (address, type, bound); + BreaksSet++; + state->CallDebug++; + *handle = (PointHandle) p; + TracePrint ((state, " returns %.8lx\n", *handle)); + return RDIError_NoError; +} + +/***************************************************************************\ +* RDI_clearbreak * +\***************************************************************************/ + +static int +RDI_clearbreak (PointHandle handle) +{ + TracePrint ((state, "RDI_clearbreak: address=%.8lx\n", handle)); + { + BreakNode *p, **prevp = &BreakList; + for (; (p = *prevp) != NULL; prevp = &p->next) + if (p == (BreakNode *) handle) + break; + if (p == NULL) + return RDIError_NoSuchPoint; + deletebreaknode (prevp); + return RDIError_NoError; + } +} + +/***************************************************************************\ +* Internal functions for breakpoint table manipulation * +\***************************************************************************/ + +static void +deletewatchnode (WatchNode ** prevp) +{ + WatchNode *p = *prevp; + if (p->datatype & Watch_AnyRead) + state->MemReadDebug--; + if (p->datatype & Watch_AnyWrite) + state->MemWriteDebug--; + *prevp = p->next; + free ((char *) p); +} + +int +removewatch (ARMword address, unsigned type) +{ + WatchNode *p, **prevp = &WatchList; + for (; (p = *prevp) != NULL; prevp = &p->next) + if (p->address == address && p->type == type) + { /* found a match */ + deletewatchnode (prevp); + return TRUE; + } + return FALSE; /* never found a match */ +} + +static WatchNode * +installwatch (ARMword address, unsigned type, unsigned datatype, + ARMword bound) +{ + WatchNode *p = (WatchNode *) malloc (sizeof (WatchNode)); + p->next = WatchList; + WatchList = p; + p->address = address; + p->type = type; + p->datatype = datatype; + p->bound = bound; + return p; +} + +/***************************************************************************\ +* RDI_setwatch * +\***************************************************************************/ + +static int +RDI_setwatch (ARMword address, unsigned type, unsigned datatype, + ARMword bound, PointHandle * handle) +{ + WatchNode *p; + TracePrint ( + (state, + "RDI_setwatch: address=%.8lx type=%d datatype=%d bound=%.8lx", + address, type, datatype, bound)); + + if (!state->CanWatch) + return RDIError_UnimplementedMessage; + + removewatch (address, type); + p = installwatch (address, type, datatype, bound); + if (datatype & Watch_AnyRead) + state->MemReadDebug++; + if (datatype & Watch_AnyWrite) + state->MemWriteDebug++; + *handle = (PointHandle) p; + TracePrint ((state, " returns %.8lx\n", *handle)); + return RDIError_NoError; +} + +/***************************************************************************\ +* RDI_clearwatch * +\***************************************************************************/ + +static int +RDI_clearwatch (PointHandle handle) +{ + TracePrint ((state, "RDI_clearwatch: address=%.8lx\n", handle)); + { + WatchNode *p, **prevp = &WatchList; + for (; (p = *prevp) != NULL; prevp = &p->next) + if (p == (WatchNode *) handle) + break; + if (p == NULL) + return RDIError_NoSuchPoint; + deletewatchnode (prevp); + return RDIError_NoError; + } +} + +/***************************************************************************\ +* RDI_execute * +\***************************************************************************/ + +static int +RDI_execute (PointHandle * handle) +{ + TracePrint ((state, "RDI_execute\n")); + if (rdi_log & 4) + { + state->CallDebug++; + state->Debug = TRUE; + } + state->EndCondition = RDIError_NoError; + state->StopHandle = 0; + + ARMul_DoProg (state); + + *handle = state->StopHandle; + state->Reg[15] -= 8; /* undo the pipeline */ + if (rdi_log & 4) + { + state->CallDebug--; + state->Debug = FALSE; + } + return (state->EndCondition); +} + +/***************************************************************************\ +* RDI_step * +\***************************************************************************/ + +static int +RDI_step (unsigned ninstr, PointHandle * handle) +{ + + TracePrint ((state, "RDI_step\n")); + if (ninstr != 1) + return RDIError_UnimplementedMessage; + if (rdi_log & 4) + { + state->CallDebug++; + state->Debug = TRUE; + } + state->EndCondition = RDIError_NoError; + state->StopHandle = 0; + ARMul_DoInstr (state); + *handle = state->StopHandle; + state->Reg[15] -= 8; /* undo the pipeline */ + if (rdi_log & 4) + { + state->CallDebug--; + state->Debug = FALSE; + } + return (state->EndCondition); +} + +/***************************************************************************\ +* RDI_info * +\***************************************************************************/ + +static int +RDI_info (unsigned type, ARMword * arg1, ARMword * arg2) +{ + switch (type) + { + case RDIInfo_Target: + TracePrint ((state, "RDI_Info_Target\n")); + /* Emulator, speed 10**5 IPS */ + *arg1 = 5 | HIGHEST_RDI_LEVEL << 5 | LOWEST_RDI_LEVEL << 8; + *arg2 = 1298224434; + return RDIError_NoError; + + case RDIInfo_Points: + { + ARMword n = RDIPointCapability_Comparison | RDIPointCapability_Range | + RDIPointCapability_Mask | RDIPointCapability_Status; + TracePrint ((state, "RDI_Info_Points\n")); + if (state->CanWatch) + n |= (Watch_AnyRead + Watch_AnyWrite) << 2; + *arg1 = n; + return RDIError_NoError; + } + + case RDIInfo_Step: + TracePrint ((state, "RDI_Info_Step\n")); + *arg1 = RDIStep_Single; + return RDIError_NoError; + + case RDIInfo_MMU: + TracePrint ((state, "RDI_Info_MMU\n")); + *arg1 = 1313820229; + return RDIError_NoError; + + case RDISignal_Stop: + TracePrint ((state, "RDISignal_Stop\n")); + state->CallDebug++; + state->EndCondition = RDIError_UserInterrupt; + return RDIError_NoError; + + case RDIVector_Catch: + TracePrint ((state, "RDIVector_Catch %.8lx\n", *arg1)); + state->VectorCatch = (unsigned) *arg1; + return RDIError_NoError; + + case RDISet_Cmdline: + TracePrint ((state, "RDI_Set_Cmdline %s\n", (char *) arg1)); + state->CommandLine = + (char *) malloc ((unsigned) strlen ((char *) arg1) + 1); + (void) strcpy (state->CommandLine, (char *) arg1); + return RDIError_NoError; + + case RDICycles: + TracePrint ((state, "RDI_Info_Cycles\n")); + arg1[0] = 0; + arg1[1] = state->NumInstrs; + arg1[2] = 0; + arg1[3] = state->NumScycles; + arg1[4] = 0; + arg1[5] = state->NumNcycles; + arg1[6] = 0; + arg1[7] = state->NumIcycles; + arg1[8] = 0; + arg1[9] = state->NumCcycles; + arg1[10] = 0; + arg1[11] = state->NumFcycles; + return RDIError_NoError; + + case RDIErrorP: + *arg1 = ARMul_OSLastErrorP (state); + TracePrint ((state, "RDI_ErrorP returns %ld\n", *arg1)); + return RDIError_NoError; + + case RDIInfo_DescribeCoPro: + { + int cpnum = *(int *) arg1; + struct Dbg_CoProDesc *cpd = (struct Dbg_CoProDesc *) arg2; + int i; + unsigned char const *map = state->CPRegWords[cpnum]; + if (map == NULL) + return RDIError_UnknownCoPro; + for (i = 0; i < cpd->entries; i++) + { + unsigned r, w = cpd->regdesc[i].nbytes / sizeof (ARMword); + for (r = cpd->regdesc[i].rmin; r <= cpd->regdesc[i].rmax; r++) + if (map[r] != w) + return RDIError_BadCoProState; + } + return RDIError_NoError; + } + + case RDIInfo_RequestCoProDesc: + { + int cpnum = *(int *) arg1; + struct Dbg_CoProDesc *cpd = (struct Dbg_CoProDesc *) arg2; + int i = -1, lastw = -1, r; + unsigned char const *map; + if ((unsigned) cpnum >= 16) + return RDIError_UnknownCoPro; + map = state->CPRegWords[cpnum]; + if (map == NULL) + return RDIError_UnknownCoPro; + for (r = 0; r < map[-1]; r++) + { + int words = map[r]; + if (words == lastw) + cpd->regdesc[i].rmax = r; + else + { + if (++i >= cpd->entries) + return RDIError_BufferFull; + cpd->regdesc[i].rmax = cpd->regdesc[i].rmin = r; + cpd->regdesc[i].nbytes = words * sizeof (ARMword); + cpd->regdesc[i].access = + Dbg_Access_Readable + Dbg_Access_Writable; + } + } + cpd->entries = i + 1; + return RDIError_NoError; + } + + case RDIInfo_Log: + *arg1 = (ARMword) rdi_log; + return RDIError_NoError; + + case RDIInfo_SetLog: + rdi_log = (int) *arg1; + return RDIError_NoError; + + case RDIInfo_CoPro: + return RDIError_NoError; + + case RDIPointStatus_Watch: + { + WatchNode *p, *handle = (WatchNode *) * arg1; + for (p = WatchList; p != NULL; p = p->next) + if (p == handle) + { + *arg1 = -1; + *arg2 = 1; + return RDIError_NoError; + } + return RDIError_NoSuchPoint; + } + + case RDIPointStatus_Break: + { + BreakNode *p, *handle = (BreakNode *) * arg1; + for (p = BreakList; p != NULL; p = p->next) + if (p == handle) + { + *arg1 = -1; + *arg2 = 1; + return RDIError_NoError; + } + return RDIError_NoSuchPoint; + } + + case RDISet_RDILevel: + if (*arg1 < LOWEST_RDI_LEVEL || *arg1 > HIGHEST_RDI_LEVEL) + return RDIError_IncompatibleRDILevels; + MYrdi_level = *arg1; + return RDIError_NoError; + + default: + return RDIError_UnimplementedMessage; + + } +} + +/***************************************************************************\ +* The emulator calls this routine at the beginning of every cycle when the * +* CallDebug flag is set. The second parameter passed is the address of the * +* currently executing instruction (i.e Program Counter - 8), the third * +* parameter is the instruction being executed. * +\***************************************************************************/ + +ARMword +ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr) +{ + + if (state->EndCondition == RDIError_UserInterrupt) + { + TracePrint ((state, "User interrupt at %.8lx\n", pc)); + state->CallDebug--; + state->Emulate = STOP; + } + else + { + BreakNode *p = BreakList; + for (; p != NULL; p = p->next) + { + switch (p->type) + { + case RDIPoint_EQ: + if (pc == p->address) + break; + continue; + case RDIPoint_GT: + if (pc > p->address) + break; + continue; + case RDIPoint_GE: + if (pc >= p->address) + break; + continue; + case RDIPoint_LT: + if (pc < p->address) + break; + continue; + case RDIPoint_LE: + if (pc <= p->address) + break; + continue; + case RDIPoint_IN: + if (p->address <= pc && pc < p->address + p->bound) + break; + continue; + case RDIPoint_OUT: + if (p->address > pc || pc >= p->address + p->bound) + break; + continue; + case RDIPoint_MASK: + if ((pc & p->bound) == p->address) + break; + continue; + } + /* found a match */ + TracePrint ((state, "Breakpoint reached at %.8lx\n", pc)); + state->EndCondition = RDIError_BreakpointReached; + state->Emulate = STOP; + state->StopHandle = (ARMword) p; + break; + } + } + return instr; +} + +void +ARMul_CheckWatch (ARMul_State * state, ARMword addr, int access) +{ + WatchNode *p; + for (p = WatchList; p != NULL; p = p->next) + if (p->datatype & access) + { + switch (p->type) + { + case RDIPoint_EQ: + if (addr == p->address) + break; + continue; + case RDIPoint_GT: + if (addr > p->address) + break; + continue; + case RDIPoint_GE: + if (addr >= p->address) + break; + continue; + case RDIPoint_LT: + if (addr < p->address) + break; + continue; + case RDIPoint_LE: + if (addr <= p->address) + break; + continue; + case RDIPoint_IN: + if (p->address <= addr && addr < p->address + p->bound) + break; + continue; + case RDIPoint_OUT: + if (p->address > addr || addr >= p->address + p->bound) + break; + continue; + case RDIPoint_MASK: + if ((addr & p->bound) == p->address) + break; + continue; + } + /* found a match */ + TracePrint ((state, "Watchpoint at %.8lx accessed\n", addr)); + state->EndCondition = RDIError_WatchpointAccessed; + state->Emulate = STOP; + state->StopHandle = (ARMword) p; + return; + } +} + +static RDI_NameList const * +RDI_cpunames () +{ + return (RDI_NameList const *) &processorconfig.count; +} + +const struct RDIProcVec armul_rdi = { + "ARMUL", + RDI_open, + RDI_close, + RDI_read, + RDI_write, + RDI_CPUread, + RDI_CPUwrite, + RDI_CPread, + RDI_CPwrite, + RDI_setbreak, + RDI_clearbreak, + RDI_setwatch, + RDI_clearwatch, + RDI_execute, + RDI_step, + RDI_info, + + 0, /*pointinq */ + 0, /*addconfig */ + 0, /*loadconfigdata */ + 0, /*selectconfig */ + 0, /*drivernames */ + + RDI_cpunames +};
armrdi.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: armfpe.h =================================================================== --- armfpe.h (nonexistent) +++ armfpe.h (revision 816) @@ -0,0 +1,1352 @@ +/* armfpe.h -- ARMulator pre-compiled FPE: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Array containing the Floating Point Emualtor (FPE). */ + + +unsigned long fpecode[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00070000, 0x00000000, 0xe92d400e, 0xeb0013ef, + 0xe28f00d4, 0xe1a00120, 0xe38004ea, 0xe3a01004, + 0xe5912000, 0xe24f3028, 0xe1500002, 0x15832000, + 0x15810000, 0xe3a00001, 0xe8bd800e, 0xe28d9040, + 0xe1a0a00e, 0xe24f7048, 0xe597b000, 0xe20b74ee, + 0xe14f8000, 0xe2088040, 0xe388809b, 0xe121f008, + 0xe35704ea, 0x004bb007, 0x01a0b10b, 0x028bf00c, + 0xe20b733b, 0xe3570339, 0x01a0ba0b, 0x01a0ba2b, + 0x059bb00c, 0x0249800c, 0x08880e00, 0x0919ff80, + 0xe24f7094, 0xe1a0f007, 0xe14f8000, 0xe2088040, + 0xe3888093, 0xe121f008, 0xe8dd7fff, 0xe1a00000, + 0xe28dd03c, 0xe8fd8000, 0xe14f8000, 0xe2088040, + 0xe3888093, 0xe121f008, 0xe8bd1fff, 0xe28dd00c, + 0xe1b0f00e, 0xe14f8000, 0xe2088040, 0xe3888093, + 0xe121f008, 0xe28dd01c, 0xe8bd1f80, 0xe28dd00c, + 0xe1b0f00e, 0x00002100, 0xe90d4007, 0xe14f0000, + 0xe24d1010, 0xe10f2000, 0xe20220c0, 0xe3822003, + 0xe121f002, 0xe169f000, 0xe8914007, 0xe24dd040, + 0xe8cd7fff, 0xe24fcf6b, 0xe58de03c, 0xe24ea004, + 0xe14f9000, 0xe20990c0, 0xe3899003, 0xe121f009, + 0xe4ba9008, 0xe20987fe, 0xe2197010, 0xe0077aa9, + 0xe0288a07, 0x02097402, 0x00077509, 0x00888007, + 0xe2097c0f, 0xe3370c01, 0x0209733e, 0x0337033a, + 0x008ff8a8, 0xea00009f, 0xea0003b7, 0xea0003b6, + 0xea000307, 0xea000306, 0xea0003b3, 0xea0003b2, + 0xea000303, 0xea000302, 0xea0003c3, 0xea0003c2, + 0xea00030d, 0xea00030c, 0xea0003bf, 0xea0003be, + 0xea000309, 0xea000308, 0xea0003cf, 0xea0003ce, + 0xea000314, 0xea000313, 0xea0003cb, 0xea0003ca, + 0xea000310, 0xea00030f, 0xea0003db, 0xea0003da, + 0xea00031a, 0xea000319, 0xea0003d7, 0xea0003d6, + 0xea000316, 0xea000315, 0xea0003e7, 0xea0003e6, + 0xea000321, 0xea000320, 0xea0003f7, 0xea0003f6, + 0xea00032b, 0xea00032a, 0xea000449, 0xea000448, + 0xea000335, 0xea000334, 0xea000459, 0xea000458, + 0xea000340, 0xea00033f, 0xea000469, 0xea000468, + 0xea00034b, 0xea00034a, 0xea000479, 0xea000478, + 0xea000355, 0xea000354, 0xea000489, 0xea000488, + 0xea00035f, 0xea00035e, 0xea000499, 0xea000498, + 0xea00036a, 0xea000369, 0xea000ac8, 0xea000ac5, + 0xea000c3d, 0xea000c3a, 0xea000b7b, 0xea000b78, + 0xea000b79, 0xea000b76, 0xea000d34, 0xea000d31, + 0xea000d08, 0xea000d05, 0xea000e34, 0xea000e31, + 0xea000e1c, 0xea000e19, 0xea000ecf, 0xea000ecc, + 0xea000c2d, 0xea000c2a, 0xea000d28, 0xea000d25, + 0xea000cfc, 0xea000cf9, 0xea00123d, 0xea00123a, + 0xeaffff55, 0xeaffff54, 0xeaffff53, 0xeaffff52, + 0xeaffff51, 0xeaffff50, 0xea0007b8, 0xea0007ec, + 0xea00073c, 0xea00073b, 0xea000806, 0xea000805, + 0xea00080f, 0xea00080e, 0xeaffff47, 0xeaffff46, + 0xeaffff45, 0xeaffff44, 0xeaffff43, 0xeaffff42, + 0xeaffff41, 0xeaffff40, 0xeaffff3f, 0xeaffff3e, + 0xea00086f, 0xea00086e, 0xeaffff3b, 0xeaffff3a, + 0xea00086b, 0xea00086a, 0xeaffff37, 0xeaffff36, + 0xea0007ff, 0xea0007fe, 0xeaffff33, 0xeaffff32, + 0xea0007fb, 0xea0007fa, 0xea000914, 0xea0008f3, + 0xea00091f, 0xea0008fb, 0xea00092b, 0xea000904, + 0xea0009dc, 0xea0009d9, 0xea0009fd, 0xea0009fa, + 0xea000ef8, 0xea000ef5, 0xea000ef6, 0xea000ef3, + 0xea000f9d, 0xea000f9a, 0xea00111e, 0xea00111b, + 0xea00111c, 0xea001119, 0xea00104e, 0xea00104b, + 0xea001147, 0xea001144, 0xea001145, 0xea001142, + 0xea00125a, 0xea001257, 0xeaffff13, 0xeaffff12, + 0xeaffff11, 0xeaffff10, 0xe3190c0e, 0x1affff0e, + 0xe3190c01, 0x13190302, 0x0affff0b, 0xe28fb016, + 0xe79b7d27, 0xe14fb000, 0xe1a0be2b, 0xe28bb010, + 0xe1170b37, 0x0affff51, 0xeaffff29, 0x8000f0f0, + 0x80000f0f, 0x8000cccc, 0x80003333, 0x8000ff00, + 0x800000ff, 0x8000aaaa, 0x80005555, 0x8000cfcf, + 0x80003030, 0x800055aa, 0x8000aa55, 0x80005faf, + 0x8000a050, 0x80000000, 0x8000ffff, 0xe1300007, + 0x5a000002, 0xea00004a, 0xe3100102, 0x1a000048, + 0xe053400b, 0x4a00002d, 0xe2745020, 0xda00001b, + 0xe092243a, 0x20822518, 0x30922518, 0xe0b11438, + 0xe1a0451a, 0x2a000006, 0xe0922fa4, 0xe2b11000, + 0x31b0f00e, 0xe3a01102, 0xe2833001, 0xe1a040a4, + 0xe1b0f00e, 0xe2833001, 0xe1a040a4, 0xe1844f82, + 0xe1a020a2, 0xe1822f81, 0xe1a01061, 0xe0922fa4, + 0xe2a11000, 0xe1b0f00e, 0xe1a04538, 0xe0922fa4, + 0xe2b11000, 0x23a01102, 0x22833001, 0xe1b0f00e, + 0xe2545040, 0xaafffff7, 0xe2444020, 0xe2645020, + 0xe0922438, 0xe2b11000, 0xe1a04518, 0xe184443a, + 0x2affffe7, 0xe0922fa4, 0xe2b11000, 0x31b0f00e, + 0xe3a01102, 0xe2833001, 0xe1a040a4, 0xe1b0f00e, + 0xe2644000, 0xe1a0300b, 0xe1a05001, 0xe1a01008, + 0xe1a08005, 0xe1a05002, 0xe1a0200a, 0xe1a0a005, + 0xe2745020, 0xdaffffe5, 0xe092243a, 0x20822518, + 0x30922518, 0xe0b11438, 0xe1a0451a, 0x2affffd0, + 0xe0922fa4, 0xe2b11000, 0x31b0f00e, 0xe3a01102, + 0xe2833001, 0xe1a040a4, 0xe1b0f00e, 0xe3100102, + 0x1affffb6, 0xe053600b, 0x4a00003d, 0x01510008, + 0x0152000a, 0x0a00004f, 0x3a000039, 0xe3a04000, + 0xe2765020, 0xda00001a, 0xe054451a, 0xe0d2263a, + 0x30422518, 0x20522518, 0xe0d11638, 0x5a000002, + 0xe0922fa4, 0xe2a11000, 0xe1b0f00e, 0xe0944004, + 0xe0b22002, 0xe0b11001, 0xe2433001, 0x5afffffa, + 0xe0922fa4, 0xe2b11000, 0x31b0f00e, 0xe3a01102, + 0xe2833001, 0xe1a040a4, 0xe1b0f00e, 0xe0544538, + 0x41b0f00e, 0xe2d22000, 0xe2d11000, 0x41b0f00e, + 0xeaffffed, 0xe3a04000, 0xe2565040, 0xaafffff6, + 0xe2466020, 0xe2665020, 0xe054751a, 0xe0d4463a, + 0x30444518, 0x20544518, 0xe0d22638, 0xe2d11000, + 0x5a000002, 0xe0922fa4, 0xe2a11000, 0xe1b0f00e, + 0xe0977007, 0xe0b44004, 0xe0b22002, 0xe0b11001, + 0xe2433001, 0x5afffff9, 0xe0922fa4, 0xe2b11000, + 0x31b0f00e, 0xe3a01102, 0xe2833001, 0xe1a040a4, + 0xe1b0f00e, 0xe2666000, 0xe2200102, 0xe1a0300b, + 0xe1a05001, 0xe1a01008, 0xe1a08005, 0xe1a05002, + 0xe1a0200a, 0xe1a0a005, 0xe3a04000, 0xe2765020, + 0xdaffffd7, 0xe054451a, 0xe0d2263a, 0x30422518, + 0x20522518, 0xe0d11638, 0x5affffbf, 0xe0922fa4, + 0xe2a11000, 0xe1b0f00e, 0xe3a03000, 0xe3a02000, + 0xe3a01000, 0xe3a04000, 0xe1b0f00e, 0xe1a07000, + 0xe1a08001, 0xe1a0a002, 0xe1a0b003, 0xe0200007, + 0xe1914002, 0x1198400a, 0x0afffff2, 0xe3b054ff, + 0xe0a3300b, 0xe185b425, 0xe043392b, 0xe92c4209, + 0xe1a04821, 0xe1c1500b, 0xe1a06822, 0xe1c2700b, + 0xe1c8900b, 0xe1a08828, 0xe1cab00b, 0xe1a0a82a, + 0xe0030b96, 0xe0020b94, 0xe0010994, 0xe0000a97, + 0xe0933000, 0xe0000a95, 0xe0b22000, 0xe0000895, + 0xe0b11000, 0x33a0e000, 0x23a0e001, 0xe0000996, + 0xe0922000, 0xe2b11000, 0xe2aee000, 0xe0000897, + 0xe0922000, 0xe2b11000, 0xe2aee000, 0xe18ee803, + 0xe1a03823, 0xe1833802, 0xe1a02822, 0xe1822801, + 0xe1a01821, 0xe181180e, 0xe3cee0ff, 0xe0000b95, + 0xe00b0b97, 0xe09eb00b, 0xe0b33000, 0xe0000896, + 0xe0b22000, 0xe0000894, 0xe0a11000, 0xe0000a94, + 0xe00a0a96, 0xe09aa003, 0xe0b22000, 0xe2a11000, + 0xe0000997, 0xe09a4000, 0xe0000995, 0xe0b22000, + 0xe2b11000, 0xe8bc4209, 0x4a000005, 0xe09bb00b, + 0xe0b44004, 0xe0b22002, 0xe0b11001, 0xe2433001, + 0x5afffff9, 0xe0922fa4, 0xe2b11000, 0x31b0f00e, + 0xe3a01102, 0xe2833001, 0xe1a040a4, 0xe1b0f00e, + 0xe1a07000, 0xe1a08001, 0xe1a0a002, 0xe1a0b003, + 0xe3a00000, 0xe3a01102, 0xe3b02100, 0xe2e23901, + 0xe0200007, 0xe1914002, 0x1198400a, 0x0affff9d, + 0xe043300b, 0xe2833901, 0xe2433001, 0xe3a0b000, + 0xe052500a, 0xe0d14008, 0x23a01003, 0x2a00000c, + 0xe1a05002, 0xe1a04001, 0xe3a01001, 0xe2433001, + 0xe0955005, 0xe0b44004, 0xe2abb000, 0xe055700a, + 0xe0d46008, 0x31b0b0ab, 0x21a05007, 0x21a04006, + 0xe0a11001, 0xe0955005, 0xe0b44004, 0xe2abb000, + 0xe055700a, 0xe0d46008, 0x31b0b0ab, 0x21a05007, + 0x21a04006, 0xe0a11001, 0xe0955005, 0xe0b44004, + 0xe2abb000, 0xe055700a, 0xe0d46008, 0x31b0b0ab, + 0x21a05007, 0x21a04006, 0xe0a11001, 0xe0955005, + 0xe0b44004, 0xe2abb000, 0xe055700a, 0xe0d46008, + 0x31b0b0ab, 0x21a05007, 0x21a04006, 0xe0b11001, + 0x3affffda, 0xe1942005, 0x01b0f00e, 0xe3a02001, + 0xe0955005, 0xe0b44004, 0xe2abb000, 0xe055700a, + 0xe0d46008, 0x31b0b0ab, 0x21a05007, 0x21a04006, + 0xe0a22002, 0xe0955005, 0xe0b44004, 0xe2abb000, + 0xe055700a, 0xe0d46008, 0x31b0b0ab, 0x21a05007, + 0x21a04006, 0xe0a22002, 0xe0955005, 0xe0b44004, + 0xe2abb000, 0xe055700a, 0xe0d46008, 0x31b0b0ab, + 0x21a05007, 0x21a04006, 0xe0a22002, 0xe0955005, + 0xe0b44004, 0xe2abb000, 0xe055700a, 0xe0d46008, + 0x31b0b0ab, 0x21a05007, 0x21a04006, 0xe0b22002, + 0x3affffda, 0xe0955005, 0xe0b44004, 0x2a000001, + 0xe1540008, 0x0155000a, 0xe2b22000, 0xe2b11000, + 0x31b0f00e, 0xe2a33000, 0xe3a01102, 0xe1b0f00e, + 0xe1b04883, 0x0affff37, 0xe2833901, 0xe2433001, + 0xe1b030a3, 0xe1a05002, 0x32414102, 0x22414101, + 0x33a07201, 0x23a07202, 0xe3a01102, 0xe0955005, + 0xe0b44004, 0xe0216007, 0x31540006, 0x20444006, + 0x20211087, 0xe1b070e7, 0x5afffff7, 0xe1942005, + 0x01b0f00e, 0xe3a02000, 0xe0955005, 0xe0b44004, + 0xe0a00000, 0xe0226007, 0xe055a006, 0xe0d48001, + 0x31b000a0, 0x21a0500a, 0x21a04008, 0x20222087, + 0x20211fa7, 0xe1b070a7, 0x1afffff2, 0xe0955005, + 0xe0b44004, 0xe0b70007, 0xe0d5a002, 0xe0d48001, + 0x31b000a0, 0x21a0500a, 0x21a04008, 0x22222001, + 0x23a07102, 0xe3a00000, 0xe0977007, 0xe0b55005, + 0xe0b44004, 0x2a000002, 0xe1540001, 0x01550002, + 0x03570101, 0xe2b22000, 0xe2b11000, 0xe2a33000, + 0x23a01102, 0xe1b0f00e, 0xe1b07004, 0x42644000, + 0xe3a0b901, 0xe3a0a000, 0xe1a08004, 0xe1b04828, + 0x01a08808, 0x128bb010, 0xe1b04c28, 0x01a08408, + 0x128bb008, 0xe1b04e28, 0x01a08208, 0x128bb004, + 0xe1b04f28, 0x01a08108, 0x128bb002, 0xe1b04fa8, + 0x01a08088, 0x024bb001, 0xe1b0f00e, 0xe1a07000, + 0xe1a0b003, 0xe24b40fe, 0xe2544c3f, 0xda000011, + 0xe2745020, 0x4a000003, 0xe3a0a000, 0xe1a08531, + 0xe1a08518, 0xe1b0f00e, 0xe1a08001, 0xe1a0a002, + 0xe2745040, 0x41b0f00e, 0xe1a0a53a, 0xe1a0a51a, + 0xe1b0f00e, 0x03a04001, 0x03a08102, 0xe3a0a000, + 0x028bb001, 0x01b0f00e, 0xe3a04000, 0xe3a08000, + 0xe3a0a000, 0xe3a0b000, 0xe1b0f00e, 0xe1a07000, + 0xe1a0b003, 0xe24b40fe, 0xe2544c3f, 0xdafffff0, + 0xe2745020, 0x4a000007, 0xe3a0a000, 0xe1b04531, + 0xe2a44000, 0xe1b08514, 0x31b0f00e, 0xe1a08068, + 0xe28bb001, 0xe1b0f00e, 0xe1a08001, 0xe1a0a002, + 0xe2745040, 0xe3e04000, 0x41b0f00e, 0xe1b0a53a, + 0xe2aaa000, 0xe1b0a51a, 0xe2b88000, 0x31b0f00e, + 0xe1a0a0aa, 0xe18aaf88, 0xe1a08068, 0xe28bb001, + 0xe1b0f00e, 0xe38ee101, 0xe24340fe, 0xe2544c3f, + 0xda000032, 0xe2745020, 0x4a000018, 0xe1a08411, + 0x01a08002, 0x11a0a002, 0x03a0a000, 0xe3a02000, + 0xe1a01531, 0xe2194060, 0x1a000007, 0xe19aa088, + 0x00088f81, 0xe0911fa8, 0x31b01511, 0x31b0f00e, + 0xe1a01061, 0xe2833001, 0xe1b0f00e, 0xe3540060, + 0x1198a00a, 0x0a000003, 0xe0304d04, 0x5a000001, + 0xe2911001, 0xeafffff3, 0xe1a01511, 0xe1b0f00e, + 0xe2745040, 0xd1b0f00e, 0xe2444020, 0xe1a08412, + 0xe1b02532, 0xe2194060, 0x1a00000a, 0xe1b0a088, + 0x00088f82, 0xe0822fa8, 0xe1b02512, 0xe2b11000, + 0x31b0f00e, 0xe1a020a2, 0xe1822f81, 0xe1a01061, + 0xe2833001, 0xe1b0f00e, 0xe3540060, 0x13580000, + 0x0afffff4, 0xe0304d04, 0x42822001, 0xeafffff1, + 0x0a000011, 0xe2194060, 0x1a000006, 0xe1918002, + 0x01b0f00e, 0xe3a01000, 0xe3a02000, 0xe3a03000, + 0xe3a04008, 0xe1a0f00e, 0xe1918002, 0x13540060, + 0x0afffff5, 0xe0304d04, 0x5afffff3, 0xe3a01102, + 0xe3b02100, 0xe2e23901, 0xe1b0f00e, 0xe2194060, + 0x1afffff4, 0xe1924081, 0x1afffff7, 0xeaffffea, + 0xe1a04000, 0xe1a00007, 0xe1a07004, 0xe1a04001, + 0xe1a01008, 0xe1a08004, 0xe1a04002, 0xe1a0200a, + 0xe1a0a004, 0xe1a04003, 0xe1a0300b, 0xe1a0b004, + 0xe1b0f00e, 0xe209ba07, 0xe08c542b, 0xe209780f, + 0xe79da727, 0xe21980ff, 0xe04a8108, 0x178d8727, + 0xe2199902, 0xe3899901, 0xe1a09789, 0xe4ba6004, + 0x14ba7004, 0xe88503c0, 0xeafffcae, 0xe209ba07, + 0xe08c542b, 0xe209780f, 0xe79da727, 0xe21980ff, + 0xe04a8108, 0x178d8727, 0xe2199902, 0xe3899905, + 0xe1a09789, 0xe4ba6004, 0xe4ba7004, 0xe4ba8000, + 0xe88503c0, 0xeafffc9f, 0xe209ba07, 0xe08c542b, + 0xe209780f, 0xe79da727, 0xe21980ff, 0xe08a8108, + 0x178d8727, 0xe2199902, 0xe3899901, 0xe1a09789, + 0xe4ba6004, 0x14ba7004, 0xe88503c0, 0xeafffc91, + 0xe209ba07, 0xe08c542b, 0xe209780f, 0xe79da727, + 0xe21980ff, 0xe08a8108, 0x178d8727, 0xe2199902, + 0xe3899905, 0xe1a09789, 0xe4ba6004, 0xe4ba7004, + 0xe4ba8000, 0xe88503c0, 0xeafffc82, 0xe209ba07, + 0xe08cc42b, 0xe209780f, 0xe337080f, 0x179da727, + 0xe21980ff, 0xe04aa108, 0xe2199902, 0xe3899901, + 0xe1a0b789, 0xe4ba8004, 0x14ba9004, 0xe88c0f00, + 0xeafffc83, 0xe209ba07, 0xe08c542b, 0xe209780f, + 0xe79da727, 0xe21980ff, 0xe04aa108, 0x178da727, + 0xe2199902, 0xe3899901, 0xe1a09789, 0xe4ba6004, + 0x14ba7004, 0xe88503c0, 0xeafffc66, 0xe209ba07, + 0xe08cc42b, 0xe209780f, 0xe337080f, 0x179da727, + 0xe21980ff, 0xe04aa108, 0xe2199902, 0xe3899905, + 0xe1a0b789, 0xe4ba8004, 0xe4ba9004, 0xe4baa000, + 0xe88c0f00, 0xeafffc66, 0xe209ba07, 0xe08c542b, + 0xe209780f, 0xe79da727, 0xe21980ff, 0xe04aa108, + 0x178da727, 0xe2199902, 0xe3899905, 0xe1a09789, + 0xe4ba6004, 0xe4ba7004, 0xe4ba8000, 0xe88503c0, + 0xeafffc48, 0xe209ba07, 0xe08cc42b, 0xe209780f, + 0xe337080f, 0x179da727, 0xe21980ff, 0xe08aa108, + 0xe2199902, 0xe3899901, 0xe1a0b789, 0xe4ba8004, + 0x14ba9004, 0xe88c0f00, 0xeafffc49, 0xe209ba07, + 0xe08c542b, 0xe209780f, 0xe79da727, 0xe21980ff, + 0xe08aa108, 0x178da727, 0xe2199902, 0xe3899901, + 0xe1a09789, 0xe4ba6004, 0x14ba7004, 0xe88503c0, + 0xeafffc2c, 0xe209ba07, 0xe08cc42b, 0xe209780f, + 0xe337080f, 0x179da727, 0xe21980ff, 0xe08aa108, + 0xe2199902, 0xe3899905, 0xe1a0b789, 0xe4ba8004, + 0xe4ba9004, 0xe4baa000, 0xe88c0f00, 0xeafffc2c, + 0xe209ba07, 0xe08c542b, 0xe209780f, 0xe79da727, + 0xe21980ff, 0xe08aa108, 0x178da727, 0xe2199902, + 0xe3899905, 0xe1a09789, 0xe4ba6004, 0xe4ba7004, + 0xe4ba8000, 0xe88503c0, 0xeafffc0e, 0xe2095a07, + 0xe08c5425, 0xe895000f, 0xe3a04002, 0xe0044729, + 0xe3844001, 0xe1340ea3, 0xe1844d23, 0xe28f7004, + 0xe28f5f6f, 0x1085f104, 0xe209780f, 0xe79da727, + 0xe21980ff, 0xe04a8108, 0x178d8727, 0xe4aa0004, + 0xe3130101, 0x14aa1000, 0xeafffbfa, 0xe2095a07, + 0xe08c5425, 0xe895000f, 0xe3a04002, 0xe0044729, + 0xe3844005, 0xe1340ea3, 0xe1844d23, 0xe28f7004, + 0xe28f5f5b, 0x1085f104, 0xe209780f, 0xe79da727, + 0xe21980ff, 0xe04a8108, 0x178d8727, 0xe4aa0004, + 0xe4aa1004, 0xe4aa2000, 0xeafffbe6, 0xe2095a07, + 0xe08c5425, 0xe895000f, 0xe3a04002, 0xe0044729, + 0xe3844001, 0xe1340ea3, 0xe1844d23, 0xe28f7004, + 0xe28f5f47, 0x1085f104, 0xe209780f, 0xe79da727, + 0xe21980ff, 0xe08a8108, 0x178d8727, 0xe4aa0004, + 0xe3130101, 0x14aa1000, 0xeafffbd2, 0xe2095a07, + 0xe08c5425, 0xe895000f, 0xe3a04002, 0xe0044729, + 0xe3844005, 0xe1340ea3, 0xe1844d23, 0xe28f7004, + 0xe28f50cc, 0x1085f104, 0xe209780f, 0xe79da727, + 0xe21980ff, 0xe08a8108, 0x178d8727, 0xe4aa0004, + 0xe4aa1004, 0xe4aa2000, 0xeafffbbe, 0xe2095a07, + 0xe08c5425, 0xe895000f, 0xe3a04002, 0xe0044729, + 0xe3844001, 0xe1340ea3, 0xe1844d23, 0xe28f7004, + 0xe28f507c, 0x1085f104, 0xe209780f, 0xe337080f, + 0x179da727, 0xe21980ff, 0xe04aa108, 0xe4aa0004, + 0xe3130101, 0x14aa1000, 0xeafffbb2, 0xe2095a07, + 0xe08c5425, 0xe895000f, 0xe3a04002, 0xe0044729, + 0xe3844001, 0xe1340ea3, 0xe1844d23, 0xe28f7004, + 0xe28f502c, 0x1085f104, 0xe209780f, 0xe79da727, + 0xe21980ff, 0xe04aa108, 0x178da727, 0xe4aa0004, + 0xe3130101, 0x14aa1000, 0xeafffb96, 0xe08ff104, + 0xeb00036b, 0xe1a0f007, 0xea0000b6, 0xeb000368, + 0xea0000ea, 0xeb000366, 0xea000123, 0xeb000364, + 0xea0001ca, 0xea000124, 0xe1a0f007, 0xeb000360, + 0xea000134, 0xeb00035e, 0xea00014b, 0xeb00035c, + 0xea0001bd, 0xeb00035a, 0xeb000359, 0xeb000358, + 0xeb000357, 0xeb000356, 0xeb000355, 0xeb000354, + 0xeb000353, 0xea000156, 0xea00016f, 0xeb000350, + 0xe1a0f007, 0xeb00034e, 0xea00018c, 0xeb00034c, + 0xea0001ad, 0xeb00034a, 0xeb000349, 0xeb000348, + 0xeb000347, 0xeb000346, 0xeb000345, 0xeb000344, + 0xeb000343, 0xea00019f, 0xea00008d, 0xeb000340, + 0xea0000c1, 0xeb00033e, 0xe1a0f007, 0xeb00033c, + 0xea00019d, 0xeb00033a, 0xeb000339, 0xeb000338, + 0xeb000337, 0xeb000336, 0xeb000335, 0xeb000334, + 0xeb000333, 0xea00024f, 0xea00024e, 0xeb000330, + 0xea00024c, 0xeb00032e, 0xea00024a, 0xeb00032c, + 0xe1a0f007, 0xe2095a07, 0xe08c5425, 0xe895000f, + 0xe3a04002, 0xe0044729, 0xe3844005, 0xe1340ea3, + 0xe1844d23, 0xe28f7004, 0xe24f5f4b, 0x1085f104, + 0xe209780f, 0xe337080f, 0x179da727, 0xe21980ff, + 0xe04aa108, 0xe4aa0004, 0xe4aa1004, 0xe4aa2004, + 0xeafffb48, 0xe2095a07, 0xe08c5425, 0xe895000f, + 0xe3a04002, 0xe0044729, 0xe3844005, 0xe1340ea3, + 0xe1844d23, 0xe28f7004, 0xe24f5f5f, 0x1085f104, + 0xe209780f, 0xe79da727, 0xe21980ff, 0xe04aa108, + 0x178da727, 0xe4aa0004, 0xe4aa1004, 0xe4aa2000, + 0xeafffb2c, 0xe2095a07, 0xe08c5425, 0xe895000f, + 0xe3a04002, 0xe0044729, 0xe3844001, 0xe1340ea3, + 0xe1844d23, 0xe28f7004, 0xe24f5f73, 0x1085f104, + 0xe209780f, 0xe337080f, 0x179da727, 0xe21980ff, + 0xe08aa108, 0xe4aa0004, 0xe3130101, 0x14aa1000, + 0xeafffb20, 0xe2095a07, 0xe08c5425, 0xe895000f, + 0xe3a04002, 0xe0044729, 0xe3844001, 0xe1340ea3, + 0xe1844d23, 0xe28f7004, 0xe24f5f87, 0x1085f104, + 0xe209780f, 0xe79da727, 0xe21980ff, 0xe08aa108, + 0x178da727, 0xe4aa0004, 0xe3130101, 0x14aa1000, + 0xeafffb04, 0xe2095a07, 0xe08c5425, 0xe895000f, + 0xe3a04002, 0xe0044729, 0xe3844005, 0xe1340ea3, + 0xe1844d23, 0xe28f7004, 0xe24f5f9b, 0x1085f104, + 0xe209780f, 0xe337080f, 0x179da727, 0xe21980ff, + 0xe08aa108, 0xe4aa0004, 0xe4aa1004, 0xe4aa2004, + 0xeafffaf8, 0xe2095a07, 0xe08c5425, 0xe895000f, + 0xe3a04002, 0xe0044729, 0xe3844005, 0xe1340ea3, + 0xe1844d23, 0xe28f7004, 0xe24f5faf, 0x1085f104, + 0xe209780f, 0xe79da727, 0xe21980ff, 0xe08aa108, + 0x178da727, 0xe4aa0004, 0xe4aa1004, 0xe4aa2000, + 0xeafffadc, 0xe3c03102, 0xe2000102, 0xe1b05883, + 0x12955802, 0x0a00000e, 0xe3320000, 0x01922c81, + 0xe2012080, 0x000220a1, 0xe0911002, 0x31a01081, + 0xe2a33000, 0xe2533dfe, 0x9a00001c, 0xe35300ff, + 0x31800b83, 0x318004a1, 0x33a03202, 0x31a0f007, + 0xea000008, 0xe1b04c03, 0xe18000a4, 0xe3a03202, + 0x13c11102, 0x11800421, 0x11a0f007, 0xe1922001, + 0x01a0f007, 0xea000015, 0xe380047f, 0xe3800502, + 0xe3a03202, 0xe3a04004, 0xe59c5080, 0xe1855004, + 0xe58c5080, 0xe1140825, 0x11a00004, 0x1a000e8a, + 0xe3540004, 0x11a0f007, 0xe3a04010, 0xeafffff5, + 0xe3730017, 0xda000005, 0xe1a01521, 0xe3811501, + 0xe2633000, 0xe1800331, 0xe3a03202, 0xe1a0f007, + 0xe3a03202, 0xe3a04008, 0xeaffffea, 0xe3c03102, + 0xe2000102, 0xe1b05883, 0x12955802, 0x0a000012, + 0xe1b04b02, 0xe2024b01, 0x000440a2, 0xe0922004, + 0xe2b11000, 0xe2a33000, 0xe0922002, 0xe0a11001, + 0xe2533b0f, 0x9a000019, 0xe2834001, 0xe3540b02, + 0x31800a03, 0x31800621, 0x31a01a01, 0x31811622, + 0x33a03206, 0x31a0f007, 0xea00000a, 0xe1b04a83, + 0xe18000a4, 0xe3a03206, 0x13c11102, 0x118005a1, + 0x11a01a81, 0x118115a2, 0x11a0f007, 0xe1922001, + 0x01a0f007, 0xea000014, 0xe380047f, 0xe380060f, + 0xe3a01000, 0xe3a03206, 0xe3a04004, 0xeaffffc1, + 0xe3730034, 0xda00000c, 0xe1a026a2, 0xe1822981, + 0xe1a016a1, 0xe3811702, 0xe2633000, 0xe2534020, + 0x21a01431, 0x32634020, 0x31800331, 0x31a01411, + 0x31811332, 0xe3a03206, 0xe1a0f007, 0xe3a01000, + 0xe3a03206, 0xe3a04008, 0xeaffffae, 0xe2000102, + 0xe1800003, 0xe3a0320a, 0xe1a0f007, 0xe3a02000, + 0xe1a03080, 0xe1b03c23, 0x133300ff, 0x11a01400, + 0x13811102, 0x12833dfe, 0x11a0f007, 0xe1933383, + 0x11a01400, 0x13c11102, 0x11a0f007, 0xe1b01480, + 0x01a0f007, 0xe3a03dfe, 0x52433001, 0x51b01081, + 0x5afffffc, 0xe1a0f007, 0xe1a01e80, 0xe3c03102, + 0xe2000102, 0xe18001a3, 0xe3a03206, 0xe21026ff, + 0x133206ff, 0x1280030e, 0x11a0f007, 0xe1800182, + 0xe3320000, 0x11a0f007, 0xe1912600, 0x01a0f007, + 0xe1a01a21, 0xe1911600, 0xe2000102, 0xe380030e, + 0x52400601, 0x51b01081, 0x5afffffc, 0xe1a01081, + 0xe1800621, 0xe1a01a01, 0xe1a0f007, 0xe3a02000, + 0xe1a03080, 0xe1b03c23, 0x133300ff, 0xe1a01400, + 0x13811102, 0x12833dfe, 0xe2000102, 0xe1800003, + 0xe3a0320a, 0x11a0f007, 0xe1800380, 0xe31000ff, + 0x13c11102, 0x11a0f007, 0xe1b01081, 0x01a0f007, + 0xe3800dfe, 0x52400001, 0x51b01081, 0x5afffffc, + 0xe1a0f007, 0xe1a03080, 0xe1b03aa3, 0x12834001, + 0x13340b02, 0xe1a02581, 0xe1a01aa1, 0xe1811580, + 0x13811102, 0x12833b0f, 0x11a0f007, 0xe1933203, + 0x11a0f007, 0xe0922002, 0xe0a11001, 0xe1924001, + 0x01a0f007, 0xe3a03b0f, 0xe1b01001, 0x52433001, + 0xe3a04000, 0x51844fa2, 0x51844081, 0x51a02082, + 0x51b01004, 0x5afffff8, 0xe1a0f007, 0xe1a03080, + 0xe1b03aa3, 0x12834001, 0x13340b02, 0x0a00000f, + 0xe1b04201, 0xe1a01a21, 0xe1811600, 0xe2014c01, + 0x000440a1, 0xe0911004, 0xe2a33000, 0xe2000102, + 0xe2533d0e, 0x9affff49, 0xe35300ff, 0x31800b83, + 0x318004a1, 0x33a03202, 0x31a0f007, 0xeaffff35, + 0xe1812600, 0xe1a01a21, 0xe1811600, 0xe2000102, + 0xe1b04c03, 0xe18000a4, 0xe3a03202, 0x118004a1, + 0x11a0f007, 0xe3320000, 0x01a0f007, 0xeaffff3f, + 0xe1a03080, 0xe1b03aa3, 0x12834001, 0x13340b02, + 0xe1a02581, 0xe1a01aa1, 0xe1811580, 0x13811102, + 0x12833b0f, 0xe2000102, 0xe1800003, 0xe3a0320a, + 0x11a0f007, 0xe1800200, 0xe31000ff, 0x11a0f007, + 0xe0922002, 0xe0a11001, 0xe1924001, 0x01a0f007, + 0xe3800b0f, 0xe1b01001, 0x52400001, 0xe3a04000, + 0x51844fa2, 0x51844081, 0x51a02082, 0x51b01004, + 0x5afffff8, 0xe1a0f007, 0xe3c03102, 0xe1a0f007, + 0x9a209a84, 0xfbcff799, 0x00003ffd, 0xe92c0080, + 0xe28f7004, 0xe3c44007, 0xeafffe2b, 0xe8bc0080, + 0xe1b05883, 0x12955802, 0x0a000099, 0xe3a05901, + 0xe2455001, 0xe1530005, 0x3a000006, 0xe2855003, + 0xe1530005, 0x0351020a, 0x33a04000, 0x33a05000, + 0x392c4ff0, 0x3a000021, 0xe92c4fcf, 0xe3a00902, + 0xe2404003, 0xe0644083, 0xebfffc46, 0xe24bb001, + 0xe24f4078, 0xe894000e, 0xebfffb4b, 0xe3a04901, + 0xe2444002, 0xe0434004, 0xe2644020, 0xe1a09431, + 0xe1510419, 0x03520000, 0x1210b102, 0x12899001, + 0xe200b102, 0xe8bc000f, 0xe92c0a00, 0xeb0000bf, + 0xe59c4004, 0xe1b04004, 0x5bfffb90, 0x4bfffb3a, + 0xe3a05901, 0xe2455001, 0xe1530005, 0x3a000051, + 0xe2855003, 0xe1530005, 0x0351020a, 0x2a000040, + 0xe3a04901, 0xe2844002, 0xe0544003, 0xe2645020, + 0xe1a03512, 0x11a02432, 0x11822511, 0x11a01431, + 0xe1a04e21, 0xe3a07003, 0xe3c1120f, 0xe0933003, + 0xe0b22002, 0xe0a11001, 0xe1a08101, 0xe1888f22, + 0xe1a0a102, 0xe18aaf23, 0xe092200a, 0xe0a11008, + 0xe2577001, 0x11a04204, 0x11844e21, 0x1afffff1, + 0xe1915002, 0x03a06000, 0x0a000019, 0xe3a0700f, + 0xe1a05205, 0xe1855e26, 0xe1a06206, 0xe1866e21, + 0xe3c1120f, 0xe0922002, 0xe0a11001, 0xe1a08101, + 0xe1888f22, 0xe0922102, 0xe0a11008, 0xe2577001, + 0x1afffff2, 0xe1a05205, 0xe1855e26, 0xe1a06206, + 0xe1866e21, 0xe1b01281, 0x3a000005, 0xe2866001, + 0xe1911002, 0x03c66001, 0xe206100f, 0xe351000a, + 0x02466001, 0xe8bc0008, 0xeb000023, 0xe2000102, + 0xe1800221, 0xe8bc0080, 0xe18000a7, 0xe1800004, + 0xe1a01005, 0xe1a02006, 0xe3a0320e, 0xe8bc4fc0, + 0xe1a0f007, 0xe8bc0030, 0xe3150102, 0x12644000, + 0xe2844001, 0xe2145102, 0x12644000, 0xe92c0030, + 0xe3a07901, 0xe3a0820a, 0xe3a0a000, 0xe287b002, + 0xebfffb3a, 0xeaffffb1, 0xe8bc0030, 0xe3150102, + 0x12644000, 0xe2444001, 0xe2145102, 0x12644000, + 0xe92c0030, 0xe3a07901, 0xe3a0820a, 0xe3a0a000, + 0xe287b002, 0xebfffad8, 0xeaffffa4, 0xe1a02003, + 0xe3a03010, 0xe0922002, 0x3352020a, 0x2242220a, + 0xe0b33003, 0x3afffffa, 0xe1a01622, 0xe3530064, + 0xa2433064, 0xa2811201, 0xaafffffb, 0xe353000a, + 0xa243300a, 0xa2811401, 0xaafffffb, 0xe1811a03, + 0xe1b0f00e, 0xe3530000, 0x1a00000a, 0xe1915002, + 0x03a0320e, 0x03a00000, 0x01a0f007, 0xe3110102, + 0x1affff5d, 0xe0922002, 0xe0b11001, 0xe2433001, + 0x5afffffb, 0xeaffff58, 0xe2000102, 0xe1800603, + 0xe3800302, 0xe18009a1, 0xe1a01681, 0xe18119a2, + 0xe1a02682, 0xe3a0320e, 0xe1a0f007, 0x9392ee8e, + 0x921d5d07, 0x00003fc3, 0xe1915002, 0x01b05a00, + 0x1200540f, 0x1355040f, 0x0a0000ac, 0xe92c4fd0, + 0xe3a07000, 0xe3a06000, 0xe1a04a00, 0xe3a05003, + 0xeb00009a, 0xe1a04001, 0xe3a05008, 0xeb000097, + 0xe1a04002, 0xe3a05008, 0xeb000094, 0xe1a02007, + 0xe1b01006, 0xe3a0303e, 0xe2833901, 0x4a000003, + 0xe0922002, 0xe0b11001, 0xe2433001, 0x5afffffb, + 0xe3a06000, 0xe3a07000, 0xe1a04200, 0xe3a05004, + 0xeb000086, 0xe1a09007, 0xeb00000c, 0xe3100101, + 0x1bfffade, 0x0bfffa88, 0xe24f70a4, 0xe8970d00, + 0xebfffa85, 0xe8bc4fd0, 0xe2935001, 0xda000090, + 0xe1b057a5, 0x1a0000a7, 0xe2044007, 0xeafffd46, + 0xe3590014, 0xd28f8084, 0xd0889209, 0xd8990d80, + 0xd1b0f00e, 0xe92c400f, 0xe3a01102, 0xe3a02000, + 0xe3a00901, 0xe2403001, 0xe3590000, 0x0a000011, + 0xe92c000f, 0xe2833003, 0xe3b0120a, 0x3bfffa6a, + 0xe1b090a9, 0x3afffffc, 0xe8bc0d80, 0x192c000f, + 0xebfffa69, 0x0a000007, 0xe8bc0d80, 0xe92c000f, + 0xe1a00007, 0xe1a01008, 0xe1a0200a, 0xe1a0300b, + 0xebfffa61, 0xeafffff1, 0xe1a07000, 0xe1a08001, + 0xe1a0a002, 0xe1a0b003, 0xe8bc400f, 0xe1b0f00e, + 0x00000000, 0x80000000, 0x00000000, 0x00003fff, + 0x00000000, 0xa0000000, 0x00000000, 0x00004002, + 0x00000000, 0xc8000000, 0x00000000, 0x00004005, + 0x00000000, 0xfa000000, 0x00000000, 0x00004008, + 0x00000000, 0x9c400000, 0x00000000, 0x0000400c, + 0x00000000, 0xc3500000, 0x00000000, 0x0000400f, + 0x00000000, 0xf4240000, 0x00000000, 0x00004012, + 0x00000000, 0x98968000, 0x00000000, 0x00004016, + 0x00000000, 0xbebc2000, 0x00000000, 0x00004019, + 0x00000000, 0xee6b2800, 0x00000000, 0x0000401c, + 0x00000000, 0x9502f900, 0x00000000, 0x00004020, + 0x00000000, 0xba43b740, 0x00000000, 0x00004023, + 0x00000000, 0xe8d4a510, 0x00000000, 0x00004026, + 0x00000000, 0x9184e72a, 0x00000000, 0x0000402a, + 0x00000000, 0xb5e620f4, 0x80000000, 0x0000402d, + 0x00000000, 0xe35fa931, 0xa0000000, 0x00004030, + 0x00000000, 0x8e1bc9bf, 0x04000000, 0x00004034, + 0x00000000, 0xb1a2bc2e, 0xc5000000, 0x00004037, + 0x00000000, 0xde0b6b3a, 0x76400000, 0x0000403a, + 0x00000000, 0x8ac72304, 0x89e80000, 0x0000403e, + 0x00000000, 0xad78ebc5, 0xac620000, 0x00004041, + 0xe0977007, 0xe0a66006, 0xe0978107, 0xe0a6af27, + 0xe08a6106, 0xe1a07008, 0xe0977e24, 0xe2a66000, + 0xe1a04204, 0xe2555001, 0x1afffff4, 0xe1b0f00e, + 0xe1a03280, 0xe1a038a3, 0xe1a026a2, 0xe1822981, + 0xe1a016a1, 0xe1811980, 0xe3c11102, 0xe2044007, + 0xeafffcb9, 0xe2144007, 0x13540005, 0x0a000003, + 0xe2000102, 0xe3540001, 0x0afffda0, 0xeafffdda, + 0xe2633000, 0xe3530040, 0xaa000008, 0xe2735020, + 0x42435020, 0x41a02531, 0x51a02332, 0x51822511, + 0xe1a01331, 0xe3a03000, 0xe2044007, 0xeafffca6, + 0xe2000102, 0xe3a01000, 0xe3a02000, 0xe1a03e84, + 0xe3a04008, 0xeafffd7b, 0xe2144007, 0x0a000003, + 0xe3a00000, 0xe3540003, 0x0afffdae, 0xbafffd71, + 0xe3a01000, 0xe3b02100, 0xe2e23902, 0xe2000102, + 0xe1800003, 0xe3540000, 0x13a0320a, 0xe3a04004, + 0xeafffd6c, 0xeafffffe, 0xe209aa0f, 0xe3190008, + 0x1a000069, 0xe2095007, 0xe08c5205, 0xe895000f, + 0xe1b04d23, 0xe28f7000, 0x1afffc87, 0xe1b04883, + 0x12944802, 0x0a00002b, 0x5a000039, 0xe354083e, + 0xe20448ff, 0x4a000049, 0xe1a048a4, 0xe2199060, + 0x1a00000e, 0xe2846002, 0xe1922611, 0xe3a02101, + 0xe0012432, 0x000220a1, 0xe264401f, 0xe1a01431, + 0xe3320000, 0x12811001, 0xe3100102, 0x12611000, + 0xe0312000, 0x4a000049, 0xe78d152a, 0xeafff805, + 0xe3590060, 0x1a000005, 0xe264401f, 0xe1a01431, + 0xe3100102, 0x12611000, 0xe78d152a, 0xeafff7fd, + 0xe0307d09, 0x5afffff7, 0xe2846001, 0xe1922611, + 0x0afffff4, 0xe264401f, 0xe1a01431, 0xe2811001, + 0xe3100102, 0x12611000, 0xe0312000, 0x4a000033, + 0xe78d152a, 0xeafff7ef, 0xe31300ff, 0x1a000003, + 0xe1921001, 0x1a000006, 0xe78d152a, 0xeafff7e9, + 0xe1921001, 0x0a000029, 0xe28f70bc, 0xe3a04001, + 0xeafffd28, 0xe02970a9, 0xe3170020, 0x0a000010, + 0xea000003, 0xe2199060, 0x0a000008, 0xe3590060, + 0x0a00000b, 0xe0307d09, 0x5a000009, 0xe3a01001, + 0xe3100102, 0x12611000, 0xe78d152a, 0xeafff7d5, + 0xe2947802, 0x5a000002, 0xe3510102, 0x03520000, + 0x8afffff5, 0xe3a01000, 0xe78d152a, 0xea000016, + 0xe354083e, 0x03510102, 0xe2000102, 0x03500102, + 0x1a00000a, 0xe3520000, 0x0affffae, 0xe2199060, + 0x0a000004, 0xe3590060, 0x0affffaa, 0xe0307d09, + 0x5affffa8, 0xea000001, 0xe3520102, 0x9affffa5, + 0xe28f7014, 0xe3a04001, 0xeafffcfe, 0xe2091007, + 0xe3510006, 0xaa000001, 0xe78d152a, 0xeafff7b5, + 0xe2811003, 0xe351000a, 0x13a01001, 0xe2099060, + 0x13590020, 0x1affffde, 0xe78d152a, 0xeafff7ad, + 0xe3190080, 0x1a000034, 0xe2097a0f, 0xe79d8527, + 0xe209b807, 0xe08cb62b, 0xe1b07008, 0x42688000, + 0xe3a0a09e, 0xe28aadfe, 0x03a0a01f, 0xe1b0c828, + 0x01a08808, 0x024aa010, 0xe1b0cc28, 0x01a08408, + 0x024aa008, 0xe1b0ce28, 0x01a08208, 0x024aa004, + 0xe1b0cf28, 0x01a08108, 0x024aa002, 0xe1b0cfa8, + 0x01a08088, 0x024aa001, 0xe1b0cc08, 0x1a000002, + 0xe3a09000, 0xe88b0780, 0xeafff79d, 0xe2199060, + 0x1a000008, 0xe1b0c08c, 0xe208c080, 0x000cc0a8, + 0xe098800c, 0xe2aaa000, 0x23a08102, 0xe3c880ff, + 0xe88b0780, 0xeafff792, 0xe2399060, 0x0afffffa, + 0xe027cc89, 0xe20cc102, 0xe0988bac, 0xe2aaa000, + 0x23a08102, 0xe3a09000, 0xe3c880ff, 0xe88b0780, + 0xeafff787, 0xe3190080, 0x1afff75f, 0xe2097a0f, + 0xe79d8527, 0xe209b807, 0xe08cb62b, 0xe1b07008, + 0x42688000, 0xe3a0a09e, 0xe28aadfe, 0x03a0a01f, + 0xe1b09828, 0x01a08808, 0x024aa010, 0xe1b09c28, + 0x01a08408, 0x024aa008, 0xe1b09e28, 0x01a08208, + 0x024aa004, 0xe1b09f28, 0x01a08108, 0x024aa002, + 0xe1b09fa8, 0x01a08088, 0x024aa001, 0xe3a09000, + 0xe88b0780, 0xeafff76a, 0xe2097a0f, 0xe79da527, + 0xe3ca801f, 0xe3d8881f, 0x1a000002, 0xe38aa000, + 0xe58ca080, 0xeafff762, 0xe24f700c, 0xe3a04001, + 0xeafffc94, 0xe2097a0f, 0xe59ca080, 0xe78da527, + 0xeafff74c, 0xe1b08e09, 0x4a000037, 0xe08c8c28, + 0xe898000f, 0xe1b04d23, 0xe28f7000, 0x1afffbae, + 0xe2097807, 0xe1a0b003, 0xe1a0a002, 0xe0208509, + 0xe1a09001, 0xe08cc627, 0xe89c000f, 0xe1b04d23, + 0xe28f7000, 0x1afffba4, 0x188c000f, 0xe3a04803, + 0xe0945883, 0x3094588b, 0x2a000015, 0xe0305008, + 0x4a000009, 0xe153000b, 0x01510009, 0x0152000a, + 0xe10f7000, 0xe2077206, 0x33877102, 0x13100102, + 0x1227720a, 0xe168f007, 0xeafff72a, 0xe19b4003, + 0x019a4002, 0x01994001, 0x0a000003, 0xe3100102, + 0x1368f102, 0x0368f202, 0xeafff722, 0xe368f206, + 0xeafff720, 0xe0945883, 0x3a000001, 0xe1915002, + 0x1a000003, 0xe094588b, 0x3affffe3, 0xe199500a, + 0x0affffe1, 0xe368f201, 0xe24fc0c0, 0xe24ccc24, + 0xe24f7038, 0xe3a04001, 0xeafffc56, 0xe2097807, + 0xe2095602, 0xe24f6074, 0xe0866c28, 0xe8960f00, + 0xe0288505, 0xeaffffca, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x80000000, + 0x00000000, 0x00003fff, 0x00000000, 0x80000000, + 0x00000000, 0x00004000, 0x00000000, 0xc0000000, + 0x00000000, 0x00004000, 0x00000000, 0x80000000, + 0x00000000, 0x00004001, 0x00000000, 0xa0000000, + 0x00000000, 0x00004001, 0x00000000, 0x80000000, + 0x00000000, 0x00003ffe, 0x00000000, 0xa0000000, + 0x00000000, 0x00004002, 0xe2097807, 0xe2095602, + 0xe24f6e11, 0xe0866c28, 0xe8960f00, 0xe0288505, + 0xea00000b, 0xe1b08e09, 0x4afffff6, 0xe08c8c28, + 0xe898000f, 0xe1b04d23, 0xe28f7000, 0x1afffb46, + 0xe2097807, 0xe1a0b003, 0xe1a0a002, 0xe0208509, + 0xe1a09001, 0xe08cc627, 0xe89c000f, 0xe1b04d23, + 0xe28f7000, 0x1afffb3c, 0x188c000f, 0xe3a04803, + 0xe0945883, 0x3094588b, 0x2a00000b, 0xe0305008, + 0x4affffa1, 0xe153000b, 0x01510009, 0x0152000a, + 0xe10f7000, 0xe2077206, 0x33877102, 0x13100102, + 0x1227720a, 0xe168f007, 0xeafff6c2, 0xe0945883, + 0x3a000001, 0xe1915002, 0x1a000003, 0xe094588b, + 0x3affffed, 0xe199500a, 0x0affffeb, 0xe368f201, + 0xeafff6b8, 0xe2099060, 0xe3590020, 0x03a07209, + 0x0a000006, 0xe3a00000, 0xe08cb42a, 0xe28f708c, + 0xe2877c05, 0xea0000de, 0xe357020e, 0x0afffff4, + 0xe24f8c02, 0xe0887c27, 0xe08cb42a, 0xe8970780, + 0xe88b0780, 0xeafff6b6, 0xe24f8f85, 0xe0887c27, + 0xe08cb42a, 0xe8970700, 0xe3a07102, 0xe88b0780, + 0xeafff6af, 0xe24f7e23, 0xe0878c28, 0xe8980d00, + 0xe3a04000, 0xea0001f3, 0xe24f7f91, 0xe0878c28, + 0xe8980d00, 0xe3a04000, 0xea0002a5, 0xe3580102, + 0x0a00040f, 0xe24f7e26, 0xe0878c28, 0xe8980d00, + 0xea00035f, 0xe3580102, 0x0a00050f, 0xe24f7f9e, + 0xe0878c28, 0xe8980d00, 0xea000456, 0xe24f7fa3, + 0xe0876c26, 0xe896000f, 0xea000463, 0xe3580102, + 0x0a0005b3, 0xe24f7e2a, 0xe0878c28, 0xe8980d00, + 0xea000546, 0xe24f7fad, 0xe0876c26, 0xe896000f, + 0xea000549, 0xe24f8fb1, 0xe0888c27, 0xe08cb42a, + 0xe898000f, 0xe3570209, 0x9a00018e, 0xea000143, + 0xe24f8e2e, 0xe0888c27, 0xe898000f, 0xea00063a, + 0xe24f8e2f, 0xe0888c27, 0xe898000f, 0xea0006dd, + 0xe24f8c03, 0xe0888c27, 0xe898000f, 0xea000790, + 0xe24f8e31, 0xe0888c27, 0xe898000f, 0xea000858, + 0xe3570102, 0x13570209, 0x1357020e, 0x1a0008fe, + 0xe24f8e33, 0xe0888c27, 0xe898000f, 0xea000880, + 0xe24f8d0d, 0xe0888c27, 0xe898000f, 0xea000992, + 0xe24f7e35, 0xe0876c26, 0xe896000f, 0xea000937, + 0xe24f7fd7, 0xe0878c28, 0xe8980d00, 0xea0005b6, + 0xe3190080, 0x1afff638, 0xe1b07e09, 0xe209aa07, + 0x4affff9e, 0xe08c7c27, 0xe08cb42a, 0xe8970780, + 0xe88b0780, 0xeafff656, 0xe3190080, 0x1afff62e, + 0xe1b07e09, 0xe209aa07, 0x4affff9a, 0xe08c7c27, + 0xe08cb42a, 0xe8970780, 0xe2277102, 0xe88b0780, + 0xeafff64b, 0xe3190080, 0x1afff623, 0xe1b07e09, + 0xe209aa07, 0x4affff89, 0xe08c7c27, 0xe08cb42a, + 0xe8970780, 0xe3c77102, 0xe88b0780, 0xeafff640, + 0xe1b07e09, 0xe209aa07, 0x4affff80, 0xe08c7c27, + 0xe08ca42a, 0xe897000f, 0xe2098080, 0xe3888040, + 0xe1580ba3, 0x21b04183, 0x3a00001d, 0xe88a000f, + 0xeafff62c, 0xe1b07e09, 0xe209aa07, 0x4affff79, + 0xe08c7c27, 0xe08ca42a, 0xe897000f, 0xe2200102, + 0xe2098080, 0xe3888040, 0xe1580ba3, 0x21b04183, + 0x3a00000f, 0xe88a000f, 0xeafff61e, 0xe1b07e09, + 0xe209aa07, 0x4affff65, 0xe08c7c27, 0xe08ca42a, + 0xe897000f, 0xe3c00102, 0xe2098080, 0xe3888040, + 0xe1580ba3, 0x21b04183, 0x3a000001, 0xe88a000f, + 0xeafff610, 0xe1a04328, 0xe1844d23, 0xe24f7018, + 0xe3540019, 0x0a00006b, 0xc3c03102, 0xe3140002, + 0x1a000034, 0xe1b05883, 0x12955802, 0x0a00001c, + 0xe2195060, 0x1a00000c, 0xe1925c81, 0xe2012080, + 0x000220a1, 0xe0911002, 0x23a01102, 0xe2a33000, + 0xe3a02000, 0xe3c110ff, 0xe2535dfe, 0x9a00001a, + 0xe35500ff, 0x31a0f007, 0xea000012, 0xe3550060, + 0x11922c01, 0x10305d05, 0x5afffff4, 0xe2911c01, + 0x23a01102, 0xe2a33000, 0xe3a02000, 0xe3c110ff, + 0xe2535dfe, 0x9a00000c, 0xe35500ff, 0x31a0f007, + 0xea000004, 0xe31300ff, 0x11a0f007, 0xe1922001, + 0x01a0f007, 0xea00000a, 0xe3a030ff, 0xe3833c7f, + 0xe3a01000, 0xe3a04004, 0xeafffb1a, 0xe3750017, + 0xda000003, 0xe2655009, 0xe1a01531, 0xe1a01511, + 0xe1a0f007, 0xe3a03000, 0xe3a02000, 0xe3a01000, + 0xe3a04008, 0xeafffb0f, 0xe1b05883, 0x12955802, + 0x0a000022, 0xe2195060, 0x1a00000f, 0xe1b04b02, + 0xe2024b01, 0x000440a2, 0xe0922004, 0xe2b11000, + 0xe2a33000, 0x23a01102, 0xe1a025a2, 0xe1a02582, + 0xe2535b0f, 0x9a00001a, 0xe2854001, 0xe3540b02, + 0x31a0f007, 0xe3a02000, 0xeaffffda, 0xe3550060, + 0x11b04a82, 0x10305d05, 0x5afffff2, 0xe2922b02, + 0xe2b11000, 0x23a01102, 0xe2a33000, 0xe1a025a2, + 0xe1a02582, 0xe2535b0f, 0x9a000009, 0xe2854001, + 0xe3540b02, 0x31a0f007, 0xe3a02000, 0xeaffffc9, + 0xe31300ff, 0x11a0f007, 0xe1922001, 0x01a0f007, + 0xeaffffcf, 0xe3750034, 0xdaffffcd, 0xe265500c, + 0xe2554020, 0x21a02431, 0x31a02532, 0x21a01412, + 0xe1a02512, 0xe1a0f007, 0xe1a03080, 0xe1b03aa3, + 0x12834001, 0x13340b02, 0x0a000023, 0xe2833b0f, + 0xe2195060, 0x1a00000f, 0xe1b04201, 0xe1a01aa1, + 0xe1811580, 0xe3811102, 0xe2014080, 0x000440a1, + 0xe0911004, 0x23a01102, 0xe2a33000, 0xe3c110ff, + 0xe3a02000, 0xe2535dfe, 0x9affffab, 0xe35500ff, + 0x31a0f007, 0xeaffffa3, 0xe1b04181, 0xe1a01aa1, + 0xe1811580, 0xe3811102, 0x13550060, 0x10305d05, + 0x5afffff1, 0xe2911c01, 0x23a01102, 0xe2a33000, + 0xe3a02000, 0xe3c110ff, 0xe2535dfe, 0x9affff9a, + 0xe35500ff, 0x31a0f007, 0xeaffff92, 0xe1833203, + 0xe1912600, 0x01a0f007, 0xe1a02581, 0xe1a01aa1, + 0xe1811580, 0xe31300ff, 0x11a0f007, 0xeaffff94, + 0xe3190080, 0x1afff54c, 0xe1b07e09, 0xe209aa07, + 0x4afffeb0, 0xe08c7c27, 0xe08cb42a, 0xe897000f, + 0xe1b04d23, 0xe28f7000, 0x1afff9c3, 0xe1a04883, + 0xe2944802, 0x0a00000b, 0xe92c4000, 0xebfff83c, + 0xe8bc4000, 0xe28f7014, 0x1afffa96, 0xe1898629, + 0xe3180080, 0x0affff4e, 0xe3190080, 0x1affff81, + 0xe88b000f, 0xeafff553, 0xe1928001, 0x0a000003, + 0xe3811101, 0xe24f701c, 0xe3a04001, 0xeafffa89, + 0xe3a02000, 0xe24f702c, 0xeaffff66, 0xe3190080, + 0x1afff529, 0xe1b07e09, 0xe209aa07, 0x4afffec0, + 0xe08c8c27, 0xe08cb42a, 0xe898000f, 0xe1b04d23, + 0xe28f7000, 0x1afff9a0, 0x1888000f, 0xe1b04883, + 0x12944802, 0x0a000063, 0xe3100102, 0x1a000059, + 0xe2833901, 0xe2433001, 0xe1b030a3, 0xe1a05002, + 0x32414102, 0x22414101, 0x33a07201, 0x23a07202, + 0xe3a01102, 0xe0955005, 0xe0b44004, 0xe0216007, + 0x31540006, 0x20444006, 0x20211087, 0xe1b070e7, + 0x5afffff7, 0xe1942005, 0x11892629, 0x12122080, + 0x03a07000, 0x0a000018, 0xe3a02000, 0xe0955005, + 0xe0b44004, 0xe0a00000, 0xe0226007, 0xe055a006, + 0xe0d48001, 0x31b000a0, 0x21a0500a, 0x21a04008, + 0x20222087, 0x20211fa7, 0xe1b070a7, 0x1afffff2, + 0xe0955005, 0xe0b44004, 0xe0b70007, 0xe0d5a002, + 0xe0d48001, 0x31b000a0, 0x21a0500a, 0x21a04008, + 0x22222001, 0x23a07102, 0xe3a00000, 0xe3190702, + 0x1a000008, 0xe1954004, 0x01944007, 0x13822001, + 0xe28f7044, 0xe3530000, 0xdaffff29, 0xe3190080, + 0x0afffef7, 0xeaffff2b, 0xe2196060, 0x1a000015, + 0xe0977007, 0xe0b55005, 0xe0b44004, 0x2a000002, + 0xe1540001, 0x01550002, 0x03570101, 0xe2b22000, + 0xe2b11000, 0xe2a33000, 0x23a01102, 0xe59c5080, + 0xe3150010, 0x0a000001, 0xe88b000f, 0xeafff4ed, + 0xe3855010, 0xe58c5080, 0xe3150601, 0x0afffff9, + 0xe3a00010, 0xea0008b4, 0xe1945005, 0x01955007, + 0x13560060, 0x0afffff0, 0xe1300c86, 0x4affffee, + 0xe2922001, 0xeaffffe9, 0xe3a014c5, 0xe3a02000, + 0xe3a030ff, 0xe1833383, 0xe3811101, 0xe24f705c, + 0xe3a04001, 0xeafffa13, 0xe3530000, 0x1a000008, + 0xe1914002, 0x0affffe3, 0xe1b01001, 0x4affff95, + 0xe0922002, 0xe0b11001, 0xe2433001, 0x5afffffb, + 0xeaffff90, 0xe1914002, 0x1affffee, 0xe3100102, + 0x0affffd5, 0xeaffffe7, 0xe3190080, 0x1afff4a6, + 0xe1b08e09, 0x4afffe1a, 0xe08c8c28, 0xe898000f, + 0xe1b04d23, 0x0a00000b, 0xe28f7024, 0xe3540008, + 0x1afff91d, 0xe3a02000, 0xe1a03080, 0xe1b03c23, + 0x133300ff, 0x11a01400, 0x13811102, 0x12833dfe, + 0x0afffa4d, 0xe888000f, 0xe1a0b003, 0xe1a0a002, + 0xe1a08001, 0xe2004102, 0xe2096807, 0xe08c6626, + 0xe896000f, 0xe1340000, 0x4a0000b6, 0xe1b04d23, + 0x0a00000b, 0xe28f7024, 0xe3540008, 0x1afff906, + 0xe3a02000, 0xe1a03080, 0xe1b03c23, 0x133300ff, + 0x11a01400, 0x13811102, 0x12833dfe, 0x0afffa36, + 0xe886000f, 0xe3a06802, 0xe0965883, 0x3096588b, + 0x2a000061, 0xe053400b, 0x4a000046, 0xe2745020, + 0xda00000e, 0xe092243a, 0x20822518, 0x30922518, + 0xe0b11438, 0xe1a0851a, 0xe1a0a088, 0x2a000011, + 0xe3190702, 0x1a00001d, 0xe19aa008, 0x13822001, + 0xe28f7090, 0xe3190080, 0x0afffe7d, 0xeafffeb1, + 0xe3540040, 0xc18aa008, 0xc3a08000, 0xaa00000b, + 0xe2444020, 0xe2645020, 0xe0922438, 0xe2b11000, + 0xe1a08518, 0xe18aa088, 0xe2a33000, 0x218aa008, + 0x21a08f82, 0x21a020a2, 0x21822f81, 0x21a01061, + 0xe3190702, 0x1a000005, 0xe19aa008, 0x13822001, + 0xe28f7030, 0xe3190080, 0x0afffe65, 0xeafffe99, + 0xe2197060, 0x1a000014, 0xe19aa088, 0x00088f82, + 0xe0922fa8, 0xe2b11000, 0xe2a33000, 0x23a01102, + 0xe0965883, 0x0a00003b, 0xe59c5080, 0xe3150010, + 0x0a000003, 0xe2099a07, 0xe08c9429, 0xe889000f, + 0xeafff45c, 0xe3855010, 0xe58c5080, 0xe3150601, + 0x0afffff7, 0xe3a00010, 0xea000823, 0xe19aa008, + 0x13570060, 0x0affffef, 0xe1300c87, 0x4affffed, + 0xe2922001, 0xeaffffe6, 0xe2644000, 0xe1a0300b, + 0xe1a05001, 0xe1a01008, 0xe1a08005, 0xe1a05002, + 0xe1a0200a, 0xe1a0a005, 0xe2745020, 0xdaffffbf, + 0xe092243a, 0x20822518, 0x30922518, 0xe0b11438, + 0xe1a0851a, 0xe1a0a088, 0x2affffc2, 0xe3190702, + 0x1affffce, 0xe19aa008, 0x13822001, 0xe24f70ac, + 0xe3190080, 0x0afffe2e, 0xeafffe62, 0xe0965883, + 0x1a000001, 0xe1925001, 0x1a000006, 0xe096588b, + 0x1affffcc, 0xe1a0300b, 0xe1a01008, 0xe1a0200a, + 0xe1915002, 0x0affffc7, 0xe3811101, 0xe24f70ec, + 0xe3a04001, 0xeafff963, 0xe3a030ff, 0xe1833383, + 0xe3a02000, 0xe3a01000, 0xe24f7f42, 0xe3a04004, + 0xeafff95c, 0xe1b04d23, 0x0a00000b, 0xe28f7024, + 0xe3540008, 0x1afff87c, 0xe3a02000, 0xe1a03080, + 0xe1b03c23, 0x133300ff, 0x11a01400, 0x13811102, + 0x12833dfe, 0x0afff9ac, 0xe886000f, 0xe0200589, + 0xeaffff73, 0xe3190080, 0x1afff3ef, 0xe1b08e09, + 0x4afffd68, 0xe08c8c28, 0xe898000f, 0xe1b04d23, + 0x0a00000b, 0xe28f7024, 0xe3540008, 0x1afff866, + 0xe3a02000, 0xe1a03080, 0xe1b03c23, 0x133300ff, + 0x11a01400, 0x13811102, 0x12833dfe, 0x0afff996, + 0xe888000f, 0xe1a0b003, 0xe1a0a002, 0xe1a08001, + 0xe2004102, 0xe2096807, 0xe08c6626, 0xe896000f, + 0xe1340000, 0x4affffd2, 0xe1b04d23, 0x0a00000b, + 0xe28f7024, 0xe3540008, 0x1afff84f, 0xe3a02000, + 0xe1a03080, 0xe1b03c23, 0x133300ff, 0x11a01400, + 0x13811102, 0x12833dfe, 0x0afff97f, 0xe886000f, + 0xe0200589, 0xe3a06802, 0xe0965883, 0x3096588b, + 0x2a00006b, 0xe053400b, 0x01510008, 0x0152000a, + 0x0a000078, 0x3a00004c, 0xe3a07000, 0xe2745020, + 0xda000015, 0xe057651a, 0xe0d2243a, 0x30422518, + 0x20522518, 0xe0d11438, 0x5a00001b, 0xe3190702, + 0x1a000029, 0xe1977006, 0x13822001, 0xe28f70c0, + 0xe3190080, 0x0afffdc2, 0xeafffdf6, 0x13a06102, + 0xe3a07001, 0xe198500a, 0x0a000029, 0xe2522001, + 0xe2d11000, 0x5a00000c, 0xea000011, 0xe3a06000, + 0xe3540040, 0xaafffff4, 0xe2444020, 0xe2645020, + 0xe057751a, 0xe0d6643a, 0x30466518, 0x20566518, + 0xe0d22438, 0xe2d11000, 0x4a000005, 0xe0977007, + 0xe0b66006, 0xe0b22002, 0xe0b11001, 0xe2433001, + 0x5afffff9, 0xe3190702, 0x1a000007, 0xe3530000, + 0xda00004c, 0xe1977006, 0x13822001, 0xe28f7030, + 0xe3190080, 0x0afffd9e, 0xeafffdd2, 0xe2195060, + 0x1a00000e, 0xe1977086, 0x00066f82, 0xe0922fa6, + 0xe2b11000, 0xe2a33000, 0x23a01102, 0xe1b03003, + 0x4a000042, 0xe59c5080, 0xe3150010, 0x0affff3c, + 0xe2099a07, 0xe08c9429, 0xe889000f, 0xeafff395, + 0xe1977006, 0x13550060, 0x0afffff3, 0xe1300c85, + 0x4afffff1, 0xe2922001, 0xeaffffec, 0xe2644000, + 0xe2200102, 0xe1a0300b, 0xe1a05001, 0xe1a01008, + 0xe1a08005, 0xe1a05002, 0xe1a0200a, 0xe1a0a005, + 0xe3a07000, 0xe2745020, 0xdaffffbf, 0xe057651a, + 0xe0d2243a, 0x30422518, 0x20522518, 0xe0d11438, + 0x5affffc5, 0xe3190702, 0x1affffd3, 0xe1977006, + 0x13822001, 0xe24f7098, 0xe3190080, 0x0afffd6c, + 0xeafffda0, 0xe0965883, 0x1a000005, 0xe1925001, + 0x1affff44, 0xe153000b, 0x0198500a, 0x03a014c1, + 0x0affff40, 0xe096588b, 0x1affffcd, 0xe2200102, + 0xe1a0300b, 0xe1a01008, 0xe1a0200a, 0xe1915002, + 0x0affffc7, 0xeaffff37, 0xe3a03000, 0xe3a02000, + 0xe3a01000, 0xeaffffc2, 0xe3a03000, 0xe3a02000, + 0xe3a01000, 0xe24f7f42, 0xe3a04008, 0xeafff895, + 0xe2633000, 0xe2734020, 0x42435020, 0x41a02531, + 0x51a02332, 0x51822411, 0xe1a01331, 0xe3a03000, + 0xeaffffb3, 0xe3190080, 0x1afff32f, 0xe1b08e09, + 0x4afffcad, 0xe08c8c28, 0xe898000f, 0xe1b04d23, + 0x0a00000b, 0xe28f7024, 0xe3540008, 0x1afff7a6, + 0xe3a02000, 0xe1a03080, 0xe1b03c23, 0x133300ff, + 0x11a01400, 0x13811102, 0x12833dfe, 0x0afff8d6, + 0xe888000f, 0xe2000102, 0xe183b000, 0xe1a0a002, + 0xe1a08001, 0xe2096807, 0xe08c6626, 0xe896000f, + 0xe1b04d23, 0x0a00000b, 0xe28f7024, 0xe3540008, + 0x1afff791, 0xe3a02000, 0xe1a03080, 0xe1b03c23, + 0x133300ff, 0x11a01400, 0x13811102, 0x12833dfe, + 0x0afff8c1, 0xe886000f, 0xe020000b, 0xe3cbb102, + 0xe3a06802, 0xe3530000, 0x135b0000, 0x0a00008c, + 0xe0965883, 0x3096588b, 0x2afffee7, 0xe3b054ff, + 0xe0a3300b, 0xe185b425, 0xe043392b, 0xe19a4088, + 0x11924081, 0x0a000064, 0xe92c4209, 0xe1a04821, + 0xe1c1500b, 0xe1a06822, 0xe1c2700b, 0xe1c8900b, + 0xe1a08828, 0xe1cab00b, 0xe1a0a82a, 0xe0030b96, + 0xe0020b94, 0xe0010994, 0xe0000a97, 0xe0933000, + 0xe0000a95, 0xe0b22000, 0xe0000895, 0xe0b11000, + 0x33a0e000, 0x23a0e001, 0xe0000996, 0xe0922000, + 0xe2b11000, 0xe2aee000, 0xe0000897, 0xe0922000, + 0xe2b11000, 0xe2aee000, 0xe18ee803, 0xe1a03823, + 0xe1833802, 0xe1a02822, 0xe1822801, 0xe1a01821, + 0xe181180e, 0xe3cee0ff, 0xe0000b95, 0xe00b0b97, + 0xe09eb00b, 0xe0b33000, 0xe0000896, 0xe0b22000, + 0xe0000894, 0xe0a11000, 0xe0000a94, 0xe00a0a96, + 0xe09aa003, 0xe0b22000, 0xe2a11000, 0xe0000997, + 0xe09aa000, 0xe0000995, 0xe0b22000, 0xe2b11000, + 0xe8bc4209, 0x5a000009, 0xe3190702, 0x1a000017, + 0xe19bb00a, 0x13822001, 0xe3530000, 0xdaffff79, + 0xe28f7078, 0xe3190080, 0x0afffccd, 0xeafffd01, + 0xe09bb00b, 0xe0baa00a, 0xe0b22002, 0xe0b11001, + 0xe2433001, 0x5afffff9, 0xe3190702, 0x1a000007, + 0xe3530000, 0xdaffff6b, 0xe19bb00a, 0x13822001, + 0xe28f7038, 0xe3190080, 0x0afffcbd, 0xeafffcf1, + 0xe2195060, 0x1a00001c, 0xe19bb08a, 0x000aaf82, + 0xe0922faa, 0xe2b11000, 0xe2a33000, 0x23a01102, + 0xe2934001, 0xda00001b, 0xe1b047a4, 0x1afffe91, + 0xe59c5080, 0xe3150010, 0x0afffe59, 0xe2099a07, + 0xe08c9429, 0xe889000f, 0xeafff2b2, 0xe19a4088, + 0x11a0200a, 0x11a01008, 0xe2433001, 0xe3190702, + 0x1affffee, 0xe3530000, 0xdaffff4a, 0xe24f7044, + 0xe3190080, 0x0afffc9e, 0xeafffcd2, 0xe19bb00a, + 0x13550060, 0x0affffe5, 0xe1300c85, 0x4affffe3, + 0xe2922001, 0xeaffffde, 0xe2633000, 0xe3530040, + 0xaaffff3c, 0xe2734020, 0x42435020, 0x41a02531, + 0x51a02332, 0x51822411, 0xe1a01331, 0xe3a03000, + 0xeaffffda, 0xe3530000, 0x1a000003, 0xe1915002, + 0x0a00000c, 0xe35b0000, 0x1affff6c, 0xe198500a, + 0x1affff6a, 0xe0965883, 0x33a03000, 0x33a02000, + 0x33a01000, 0x3affffcd, 0xe1915002, 0x1afffe59, + 0xe3a014c2, 0xeafffe57, 0xe096588b, 0x3affffc7, + 0xe198500a, 0x1afffe48, 0xe1a0300b, 0xeafffff7, + 0xe3190080, 0x1afff25c, 0xe2096807, 0xe08c6626, + 0xe896000f, 0xe1b04d23, 0x0a00000b, 0xe28f7024, + 0xe3540008, 0x1afff6d4, 0xe3a02000, 0xe1a03080, + 0xe1b03c23, 0x133300ff, 0x11a01400, 0x13811102, + 0x12833dfe, 0x0afff804, 0xe886000f, 0xe2000102, + 0xe183b000, 0xe1a0a002, 0xe1a08001, 0xe1b06e09, + 0x4afffbd1, 0xe08c6c26, 0xe896000f, 0xe1b04d23, + 0x0a000035, 0xe28f7024, 0xe3540008, 0x1afff6be, + 0xe3a02000, 0xe1a03080, 0xe1b03c23, 0x133300ff, + 0x11a01400, 0x13811102, 0x12833dfe, 0x0afff7ee, + 0xe886000f, 0xea000028, 0xe3190080, 0x1afff232, + 0xe1b08e09, 0x4afffbb6, 0xe08c8c28, 0xe898000f, + 0xe1b04d23, 0x0a00000b, 0xe28f7024, 0xe3540008, + 0x1afff6a9, 0xe3a02000, 0xe1a03080, 0xe1b03c23, + 0x133300ff, 0x11a01400, 0x13811102, 0x12833dfe, + 0x0afff7d9, 0xe888000f, 0xe2000102, 0xe183b000, + 0xe1a0a002, 0xe1a08001, 0xe2096807, 0xe08c6626, + 0xe896000f, 0xe1b04d23, 0x0a00000b, 0xe28f7024, + 0xe3540008, 0x1afff694, 0xe3a02000, 0xe1a03080, + 0xe1b03c23, 0x133300ff, 0x11a01400, 0x13811102, + 0x12833dfe, 0x0afff7c4, 0xe886000f, 0xe020000b, + 0xe3cbb102, 0xe1b04883, 0x11b0588b, 0x12944802, + 0x12955802, 0x0a000082, 0xe043300b, 0xe2833901, + 0xe2433001, 0xe3a0b000, 0xe052500a, 0xe0d14008, + 0x23a01003, 0x2a00000c, 0xe1a05002, 0xe1a04001, + 0xe3a01001, 0xe2433001, 0xe0955005, 0xe0b44004, + 0xe2abb000, 0xe055700a, 0xe0d46008, 0x31b0b0ab, + 0x21a05007, 0x21a04006, 0xe0a11001, 0xe0955005, + 0xe0b44004, 0xe2abb000, 0xe055700a, 0xe0d46008, + 0x31b0b0ab, 0x21a05007, 0x21a04006, 0xe0a11001, + 0xe0955005, 0xe0b44004, 0xe2abb000, 0xe055700a, + 0xe0d46008, 0x31b0b0ab, 0x21a05007, 0x21a04006, + 0xe0a11001, 0xe0955005, 0xe0b44004, 0xe2abb000, + 0xe055700a, 0xe0d46008, 0x31b0b0ab, 0x21a05007, + 0x21a04006, 0xe0b11001, 0x3affffda, 0xe1942005, + 0x11892629, 0x12122080, 0x0a000025, 0xe3a02001, + 0xe0955005, 0xe0b44004, 0xe2abb000, 0xe055700a, + 0xe0d46008, 0x31b0b0ab, 0x21a05007, 0x21a04006, + 0xe0a22002, 0xe0955005, 0xe0b44004, 0xe2abb000, + 0xe055700a, 0xe0d46008, 0x31b0b0ab, 0x21a05007, + 0x21a04006, 0xe0a22002, 0xe0955005, 0xe0b44004, + 0xe2abb000, 0xe055700a, 0xe0d46008, 0x31b0b0ab, + 0x21a05007, 0x21a04006, 0xe0a22002, 0xe0955005, + 0xe0b44004, 0xe2abb000, 0xe055700a, 0xe0d46008, + 0x31b0b0ab, 0x21a05007, 0x21a04006, 0xe0b22002, + 0x3affffda, 0xe3190702, 0x1a000007, 0xe1954004, + 0x13822001, 0xe3530000, 0xdafffe62, 0xe28f7048, + 0xe3190080, 0x0afffbb6, 0xeafffbea, 0xe2197060, + 0x1a000014, 0xe0955005, 0xe0b44004, 0x2a000002, + 0xe1540008, 0x0155000a, 0x011500a2, 0xe2b22000, + 0xe2b11000, 0xe2a33000, 0x23a01102, 0xe2934001, + 0xdaffff10, 0xe1b047a4, 0x1afffd86, 0xe59c5080, + 0xe3150010, 0x0afffd4e, 0xe2099a07, 0xe08c9429, + 0xe889000f, 0xeafff1a7, 0xe1945005, 0x13570060, + 0x0afffff1, 0xe1300c87, 0x4affffef, 0xe2922001, + 0xeaffffea, 0xe1b04883, 0x1a000013, 0xe1915002, + 0x1a00000d, 0xe1b0588b, 0x0198600a, 0x03a014c3, + 0x03a030ff, 0x01833383, 0x0afffd6a, 0xe2955802, + 0x1affffe8, 0xe198600a, 0x0affffe6, 0xe1a01008, + 0xe1a0200a, 0xe1a0300b, 0xeafffd62, 0xe0922002, + 0xe0b11001, 0xe2433001, 0x5afffffb, 0xe1b0588b, + 0x1a000010, 0xe198600a, 0x1a00000a, 0xe2944802, + 0x1a000001, 0xe1916002, 0x1afffd56, 0xe3a01000, + 0xe3a02000, 0xe3a030ff, 0xe1833383, 0xe24f70bc, + 0xe3a04002, 0xeafff6b7, 0xe09aa00a, 0xe0b88008, + 0xe24bb001, 0x5afffffb, 0xe2956802, 0x12946802, + 0x1affff50, 0xe2946802, 0x1a000006, 0xe1916002, + 0x1afffd44, 0xe2956802, 0x1affffbf, 0xe198600a, + 0x03a01331, 0x0afffd3f, 0xe198600a, 0x0afffe09, + 0xe1a01008, 0xe1a0200a, 0xe1a0300b, 0xeafffd39, + 0xe3190080, 0x1afff144, 0xe2096807, 0xe08c6626, + 0xe896000f, 0xe1b04d23, 0xe28f7000, 0x1afff5be, + 0x1886000f, 0xe2000102, 0xe183b000, 0xe1a0a002, + 0xe1a08001, 0xe1b06e09, 0x4afffacd, 0xe08c6c26, + 0xe896000f, 0xe1b04d23, 0xe28f7000, 0x1afff5b2, + 0x1886000f, 0xea000014, 0xe3190080, 0x1afff12e, + 0xe1b08e09, 0x4afffabc, 0xe08c8c28, 0xe898000f, + 0xe1b04d23, 0xe28f7000, 0x1afff5a7, 0x1888000f, + 0xe2000102, 0xe183b000, 0xe1a0a002, 0xe1a08001, + 0xe2096807, 0xe08c6626, 0xe896000f, 0xe1b04d23, + 0xe28f7000, 0x1afff59c, 0x1886000f, 0xe1a0700b, + 0xe3cbb102, 0xe1b04883, 0x12944802, 0x11b0588b, + 0x12955802, 0x0a00004e, 0xe92c4200, 0x5a000035, + 0xe24b4c3f, 0xe24440fe, 0xe3540010, 0xca00002a, + 0xe19a5418, 0x1a00002f, 0xe2649020, 0xe1a09938, + 0xe0000f89, 0xe92c0080, 0xe3a08102, 0xe3a0a000, + 0xe3a07901, 0xe257b001, 0xe92c0d80, 0x3bfff2b6, + 0xe1b090a9, 0x3afffffc, 0xe8bc0d80, 0x192c000f, + 0xebfff2b5, 0xe2834001, 0x0a000009, 0xe3540902, + 0xaa000010, 0xe8bc0d80, 0xe92c000f, 0xe1a00007, + 0xe1a01008, 0xe1a0200a, 0xe1a0300b, 0xebfff2aa, + 0xeaffffee, 0xe8bc0080, 0xe3170102, 0x1bfff2f3, + 0xe8bc4200, 0xe2934001, 0xdafffe6a, 0xe1b047a4, + 0x1afffce0, 0xea0000cb, 0xe28cc010, 0xe8bc4280, + 0xe3170102, 0x1afffda3, 0xeafffcda, 0xe3540040, + 0x2a000012, 0xe2545020, 0x21b0651a, 0x0a000010, + 0xe19a6418, 0x0a00000e, 0xe3100102, 0x1a00000e, + 0xe92c0001, 0xe3a00000, 0xe92c0d80, 0xe3c99601, + 0xeb0000e1, 0xe8bc0d80, 0xebfff28b, 0xeb000166, + 0xe8bc4201, 0x0a0000b3, 0xe28f7e2f, 0xeafff629, + 0x13b05100, 0x33a00000, 0xeafffff0, 0xe8bc4200, + 0xe3a014c7, 0xe3a02000, 0xe3a030ff, 0xe1833383, + 0xeafffcb8, 0xe3540000, 0x1a00001e, 0xe3530000, + 0x0a000002, 0xe1916002, 0x1afffcb2, 0xea000001, + 0xe1916002, 0x1a000010, 0xe1b0588b, 0x1a000006, + 0xe198600a, 0x03a01102, 0x03a02000, 0x03a00000, + 0x03a03901, 0x02433001, 0xea000096, 0xe2955802, + 0x1a000094, 0xe198600a, 0x0a000092, 0xe1a01008, + 0xe1a0200a, 0xe1a0300b, 0xeafffc9e, 0xe0922002, + 0xe0b11001, 0xe2433001, 0x5afffffb, 0xe1b0588b, + 0x12955802, 0x1affff8f, 0xe35b0000, 0x0a000008, + 0xe1a01008, 0xe1a0200a, 0xe1a00007, 0xe1a0300b, + 0xe198600a, 0x1afffc8f, 0xe3100102, 0x13a03000, + 0xea00007c, 0xe198600a, 0x0affffdd, 0xe09aa00a, + 0xe0b88008, 0xe24bb001, 0x5afffffb, 0xe92c4200, + 0xeaffffb4, 0xe3190080, 0x1afff08f, 0xe1b08e09, + 0x4afffa4e, 0xe08c8c28, 0xe898000f, 0xe1b04d23, + 0xe28f7000, 0x1afff508, 0x1888000f, 0xe2000102, + 0xe183b000, 0xe1a0a002, 0xe1a08001, 0xe2096807, + 0xe08c6626, 0xe896000f, 0xe1b04d23, 0xe28f7000, + 0x1afff4fd, 0x1886000f, 0xe1a0700b, 0xe3cbb102, + 0xe1b04883, 0x12944802, 0x11b0588b, 0x12955802, + 0x0a00000a, 0xe92c400f, 0xe92c0d80, 0xebfff27f, + 0xebfff36f, 0xe8bc0d80, 0xebfff227, 0xe2200102, + 0xe8bc0d80, 0xebfff178, 0xe8bc4000, 0xea00004d, + 0xe1b04883, 0x1a000010, 0xe1915002, 0x1a00000a, + 0xe1b0588b, 0x0198600a, 0x0a000013, 0xe2955802, + 0x1a000015, 0xe198600a, 0x0a000013, 0xe1a01008, + 0xe1a0200a, 0xe1a0300b, 0xeafffc4e, 0xe0922002, + 0xe0b11001, 0xe2433001, 0x5afffffb, 0xe1b0588b, + 0x1a000012, 0xe198600a, 0x1a00000c, 0xe2944802, + 0x1a000001, 0xe1916002, 0x1afffc42, 0xe3a01333, + 0xe3b02100, 0xe2e23902, 0xeafffc3e, 0xe3a00000, + 0xe3a01000, 0xe3a02000, 0xe3a03000, 0xea000029, + 0xe09aa00a, 0xe0b88008, 0xe24bb001, 0x5afffffb, + 0xe2956802, 0x12946802, 0x1affffc9, 0xe2946802, + 0x1a000008, 0xe1916002, 0x1afffc2e, 0x03a01333, + 0xe2956802, 0x1afffc2b, 0xe198600a, 0x11a01008, + 0x11a0200a, 0xeafffc27, 0xe198600a, 0x0a000015, + 0xe1a01008, 0xe1a0200a, 0xe1a0300b, 0xeafffc21, + 0xe3190080, 0x1afff02c, 0xe1b07e09, 0x4afff9cb, + 0xe08c8c27, 0xe898000f, 0xe1b04d23, 0xe28f7000, + 0x1afff4a5, 0x1888000f, 0xe1b04883, 0x12944802, + 0x0a00001d, 0xe3100102, 0x1a000016, 0xe92c4000, + 0xeb000029, 0xe8bc4000, 0xe3190702, 0x1a000005, + 0xe28f7018, 0xe3530000, 0xdafffa5d, 0xe3190080, + 0x0afffa2b, 0xeafffa5f, 0xe3530000, 0xba000006, + 0xe59c5080, 0xe3150010, 0x0afffbd1, 0xe2099a07, + 0xe08c9429, 0xe889000f, 0xeafff02a, 0xe3730040, + 0xcafffcce, 0xeafffa4e, 0xe3a014c6, 0xe3a02000, + 0xe3a030ff, 0xe1833383, 0xeafffbf6, 0xe3530000, + 0x1a000008, 0xe1914002, 0x0afffff6, 0xe1b01001, + 0x4affffdb, 0xe0922002, 0xe0b11001, 0xe2433001, + 0x5afffffb, 0xeaffffd6, 0xe1914002, 0x1afffbe9, + 0xe3100102, 0x0affffe1, 0xeaffffea, 0xe28f4f52, + 0xe8940500, 0xe1510008, 0x0152000a, 0xe1a0a0a2, + 0xe18aaf81, 0xe1a080a1, 0xe3888102, 0xe3a0b0fe, + 0xe18bb30b, 0xe043400b, 0x92444001, 0xe92c4210, + 0xe1a0300b, 0x8a000005, 0xe3c88101, 0xe0922002, + 0xe0b11001, 0xe2433001, 0x5a000003, 0xea000008, + 0xe3a00102, 0xe2722000, 0xe2f11000, 0x03520000, + 0x0a000035, 0xe0922002, 0xe0b11001, 0xe2433001, + 0x5afffff9, 0xe3a07000, 0xebfff1e0, 0xe92c000f, + 0xebfff185, 0xe92c000f, 0xe28f90c4, 0xe8b90d00, + 0xebfff125, 0xe89c0d80, 0xebfff183, 0xe8b90d00, + 0xebfff0d8, 0xe89c0d80, 0xebfff17f, 0xe8b90d00, + 0xebfff11d, 0xe89c0d80, 0xe92c000f, 0xe3a00102, + 0xe8b9000e, 0xebfff178, 0xe8b90d00, 0xebfff0cd, + 0xe28c4010, 0xe8940d80, 0xebfff173, 0xe8b90d00, + 0xebfff111, 0xe8bc0d80, 0xebfff1c4, 0xe8bc0d80, + 0xebfff16d, 0xe89c0d80, 0xebfff16b, 0xe8bc0d80, + 0xebfff0bd, 0xe8bc0010, 0xebfff25e, 0xe92c000f, + 0xe3a00000, 0xe8b9000e, 0xebfff163, 0xe8bc0d80, + 0xebfff0b5, 0xe8bc0200, 0xe3190601, 0xe28f7074, + 0x18970d00, 0x1bfff15c, 0xe8bc8000, 0xe3a00000, + 0xe3a03000, 0xe28f9050, 0xeaffffed, 0xb504f333, + 0xf9de6484, 0x8eac025b, 0x3e7076bb, 0x00004004, + 0x9c041fd0, 0xa933ef60, 0x00004007, 0xc05ff4e0, + 0x6c83bb96, 0x00004008, 0xca20ad9a, 0xb5e946e9, + 0x00003ffe, 0x83125100, 0xb57f6509, 0x00004003, + 0x803ff895, 0x9dacd228, 0x00004005, 0xb17217f7, + 0xd1cf79ac, 0x00003ffe, 0xde5bd8a9, 0x37287195, + 0x00003ffd, 0xe3190080, 0x1affef83, 0xe1b07e09, + 0x4afff926, 0xe08c8c27, 0xe898000f, 0xe1b04d23, + 0xe28f7000, 0x1afff3fc, 0x1888000f, 0xe1a04883, + 0xe2944802, 0x0a000005, 0xe92c4000, 0xeb00000a, + 0xe8bc4000, 0x0affff57, 0xe24f7d0a, 0xeafff4cd, + 0xe1914002, 0x1afffb63, 0xe3100102, 0x0affff5b, + 0xe3a00000, 0xe3a03000, 0xeaffff58, 0xe28f4f6e, + 0xe3100102, 0x128f4f72, 0xe8b40d00, 0xe153000b, + 0x01510008, 0x0152000a, 0x8a00005d, 0xe8940d00, + 0xe153000b, 0x01510008, 0x0152000a, 0x3a000052, + 0xe92c421f, 0xe28f9e1b, 0xe3a07000, 0xe8b90d00, + 0xebfff111, 0xebfff238, 0xe3170102, 0x12644000, + 0xe58c4010, 0xe92c0d80, 0xe3a00000, 0xe8b9000e, + 0xebfff109, 0xe8bc0d80, 0xe92c000f, 0xe8b9000e, + 0xe3a00102, 0xebfff104, 0xe92c000f, 0xe28c4020, + 0xe894000f, 0xebfff20c, 0xe3170102, 0x0bfff09e, + 0x1bfff054, 0xe1a0400c, 0xe92c000f, 0xe894000f, + 0xebfff04d, 0xe8bc0d80, 0xebfff04b, 0xe28cc010, + 0xe8bc0d80, 0xebfff048, 0xe88c000f, 0xebfff0ee, + 0xe92c000f, 0xe3a07000, 0xe8b90d00, 0xebfff0ee, + 0xe8b90d00, 0xebfff043, 0xe89c0d80, 0xebfff0ea, + 0xe8b90d00, 0xebfff03f, 0xe89c0d80, 0xebfff0e6, + 0xe8b90d00, 0xebfff03b, 0xe89c0d80, 0xe92c000f, + 0xe3a00000, 0xe8b9000e, 0xebfff0df, 0xe8b90d00, + 0xebfff034, 0xe28c7010, 0xe8970d80, 0xebfff0da, + 0xe8b90d00, 0xebfff02f, 0xe28c7020, 0xe8970d80, + 0xebfff0d5, 0xe8bc0d80, 0xe92c000f, 0xe2200102, + 0xebfff025, 0xe1a07000, 0xe1a08001, 0xe1a0a002, + 0xe1a0b003, 0xe8bc000f, 0xebfff120, 0xe8b90d00, + 0xebfff020, 0xe28cc020, 0xe8bc4210, 0xe2844001, + 0xe0833004, 0xe3b04000, 0xe1a0f00e, 0xe3b00000, + 0xe3a01102, 0xe3a02000, 0xe3a03901, 0xe2433001, + 0xe1a0f00e, 0xe3100102, 0xe3a00000, 0xe3a01000, + 0xe3a02000, 0x13a03000, 0x13a04008, 0x03a030ff, + 0x01833383, 0x03b04004, 0xe1a0f00e, 0xb17217f7, + 0xd1cf79ab, 0x0000400c, 0x80000000, 0x00000000, + 0x00003fbe, 0xb21dfe7f, 0x09e2baa9, 0x0000400c, + 0x80000000, 0x00000000, 0x00003fbe, 0xb8aa3b29, + 0x5c17f0bc, 0x00003fff, 0xde8082e3, 0x08654362, + 0x00003ff2, 0xb1800000, 0x00000000, 0x00003ffe, + 0xc99b1867, 0x2822a93e, 0x00003fea, 0xa57862e1, + 0x46a6fb39, 0x00003ff4, 0xe8b9428e, 0xfecff592, + 0x00003ffa, 0x80000000, 0x00000000, 0x00003ffe, + 0x845a2157, 0x3490f106, 0x00003ff0, 0xf83a5f91, + 0x50952c99, 0x00003ff7, 0x80000000, 0x00000000, + 0x00003ffd, 0x80000000, 0x00000000, 0x00003ffe, + 0xe3190080, 0x1affeecc, 0xe1b07e09, 0x4afff873, + 0xe08c8c27, 0xe898000f, 0xe1b04d23, 0xe28f7000, + 0x1afff345, 0x1888000f, 0xe1a04883, 0xe2944802, + 0x0a000006, 0xe92c4000, 0xeb000007, 0xe8bc4000, + 0x0afffea0, 0xe24f705c, 0xe2477c05, 0xeafff415, + 0xe1914002, 0x03a01332, 0xeafffaaa, 0xe28f4f8f, + 0xe8b40d00, 0xe153000b, 0x01510008, 0x0152000a, + 0x8a00006c, 0xe1b01001, 0x5a000063, 0xe92c421f, + 0xe3190601, 0xe28f9e22, 0xe3a07000, 0xe8b90d00, + 0xebfff061, 0xebfff188, 0x1b00006d, 0xe58c4010, + 0xe92c0d80, 0xe3a00000, 0xe8b9000e, 0xebfff05a, + 0xe8bc0d80, 0xe92c000f, 0xe8b9000e, 0xe3a00102, + 0xebfff055, 0xe92c000f, 0xe28c4020, 0xe894000f, + 0xebfff15d, 0xe3170102, 0x0bffefef, 0x1bffefa5, + 0xe1a0400c, 0xe92c000f, 0xe894000f, 0xebffef9e, + 0xe8bc0d80, 0xebffef9c, 0xe28cc010, 0xe8bc0d80, + 0xebffef99, 0xe3a04c3f, 0xe38440df, 0xe1530004, + 0xba000037, 0xe88c000f, 0xebfff03b, 0xe92c000f, + 0xe3a07000, 0xe8b90d00, 0xebfff03b, 0xe8b90d00, + 0xebffefd9, 0xe89c0d80, 0xebfff037, 0xe8b90d00, + 0xebffef8c, 0xe89c0d80, 0xebfff033, 0xe8b90d00, + 0xebffefd1, 0xe89c0d80, 0xebfff02f, 0xe8b90d00, + 0xebffef84, 0xe89c0d80, 0xe92c000f, 0xe3a00102, + 0xe8b9000e, 0xebfff028, 0xe8b90d00, 0xebffef7d, + 0xe28c7010, 0xe8970d80, 0xebfff023, 0xe8b90d00, + 0xebffefc1, 0xe28c7010, 0xe8970d80, 0xebfff01e, + 0xe28c7020, 0xe8970d80, 0xebfff01b, 0xe28c7020, + 0xe8970d80, 0xebffef6c, 0xe8bc0d80, 0xe28cc020, + 0xe8bc0010, 0xe3140001, 0x12200102, 0x1bfff1a7, + 0xe29b4902, 0x4a000018, 0xe35b0000, 0x0198400a, + 0x0a000015, 0xebfff061, 0xe8bc4200, 0xe3b04000, + 0xe1a0f00e, 0xe24cc010, 0xe3a07000, 0xe3a08102, + 0xe3b0a100, 0xe2eab901, 0xeaffffeb, 0xe1914002, + 0x0affff99, 0xe2433001, 0xe0922002, 0xe0b11001, + 0x5afffffb, 0xeaffff94, 0xe3a01332, 0xe3b02100, + 0xe2f23902, 0xe3a04001, 0xe1a0f00e, 0xe3a01000, + 0xe3b02100, 0xe2f33902, 0xe3a04004, 0xe8bc4200, + 0xe1a0f00e, 0xe2844001, 0xe35b0000, 0x03a08102, + 0xe3a06901, 0x0246b002, 0x01a0f00e, 0xe2466002, + 0xe04b6006, 0xe3a05102, 0xe153000b, 0x01510008, + 0x0152000a, 0x20888635, 0x21a0f00e, 0xe0588635, + 0x51a08088, 0x524bb001, 0xe2444001, 0xe1a0f00e, + 0xc90fdaa2, 0x00000000, 0x0000401d, 0xa2f9836e, + 0x4e44152a, 0x00003ffe, 0x95777a5c, 0xf72cece6, + 0x00003fed, 0xc9100000, 0x00000000, 0x00003fff, + 0x85bba783, 0xb3c748a9, 0x00003fea, 0xa37b24c8, + 0x4a42092e, 0x00003ff3, 0xd23cf50b, 0xf10aca84, + 0x00003ff9, 0xeef5823f, 0xdecea969, 0x00003ffd, + 0x80000000, 0x00000000, 0x00003fff, 0x95d5b975, + 0x16391da8, 0x00003fef, 0xe0741531, 0xdd56f650, + 0x00003ff6, 0x8895af2a, 0x6847fcd5, 0x00003ffc, + 0xe3190080, 0x1affee00, 0xe1b07e09, 0x4afff7ab, + 0xe08c8c27, 0xe898000f, 0xe1b04d23, 0xe28f7000, + 0x1afff279, 0x1888000f, 0xe1a04883, 0xe2944802, + 0x0a000015, 0xe1c00589, 0xe92c4000, 0xe1914002, + 0x12433001, 0xebffff38, 0x1a000012, 0xe92c000f, + 0xebffefa1, 0xe3a08102, 0xe3b0a100, 0xe2eab901, + 0xebffeef8, 0xe1a07000, 0xe1a08001, 0xe1a0a002, + 0xe1a0b003, 0xe8bc000f, 0xebffeff0, 0xe1914002, + 0x12833001, 0xe8bc4000, 0xeafffdc2, 0xe1914002, + 0x03a014c9, 0xeafff9cf, 0xe8bc4000, 0xe3540004, + 0x03a03000, 0x03a00000, 0x0afffdba, 0xe3a014c9, + 0xe3b02100, 0xe2e23902, 0xeafff9c6, 0xe3190080, + 0x1affedd1, 0xe1b07e09, 0x4afff780, 0xe08c8c27, + 0xe898000f, 0xe1b04d23, 0xe28f7000, 0x1afff24a, + 0x1888000f, 0xe1b04883, 0x0a00006b, 0x52944802, + 0x4a000072, 0xe92c4201, 0xe3a00000, 0xe3a05901, + 0xe2455002, 0xe1530005, 0xaa000009, 0xe2094501, + 0xe92c0010, 0xe3a04901, 0xe2444021, 0xe1530004, + 0xba000049, 0xe92c000f, 0xebffef6b, 0xe92c000f, + 0xea000012, 0xe2094501, 0xe2244501, 0xe92c0010, + 0xe3a00102, 0xe3a08102, 0xe3b0a100, 0xe2eab901, + 0xebffeebc, 0xe1914002, 0x0a00003b, 0xe2433001, + 0xe24cc010, 0xe92c000f, 0xebfff01c, 0xe2200102, + 0xe2833001, 0xe28c4010, 0xe884000f, 0xe89c000f, + 0xe28f9f59, 0xe8b90d00, 0xebffeef7, 0xe89c0d80, + 0xebffef55, 0xe8b90d00, 0xebffeeaa, 0xe89c0d80, + 0xebffef51, 0xe8b90d00, 0xebffeeef, 0xe89c0d80, + 0xebffef4d, 0xe8b90d00, 0xebffeea2, 0xe89c0d80, + 0xebffef49, 0xe8b90d00, 0xebffeee7, 0xe89c0d80, + 0xe92c000f, 0xe3a00102, 0xe8b9000e, 0xebffef42, + 0xe8b90d00, 0xebffee97, 0xe28c7010, 0xe8970d80, + 0xebffef3d, 0xe8b90d00, 0xebffeedb, 0xe28c7010, + 0xe8970d80, 0xebffef38, 0xe8b90d00, 0xebffee8d, + 0xe28c7010, 0xe8970d80, 0xebffef33, 0xe8b90d00, + 0xebffeed1, 0xe28c7010, 0xe8970d80, 0xebffef2e, + 0xe8bc0d80, 0xe28cc010, 0xebffef80, 0xe89c0d80, + 0xebffef29, 0xe8bc0d80, 0xebffee7b, 0xe8bc0230, + 0xe3190501, 0x0a000008, 0xe3150102, 0x028f5c01, + 0x128f5f46, 0xe0855924, 0x02200102, 0xe8950d00, + 0xebffee74, 0xe8bc4000, 0xeafffd46, 0xe3150102, + 0xe28f50dc, 0xe0855924, 0xe8950d00, 0xebffee6d, + 0x12200102, 0xe8bc4000, 0xeafffd3e, 0xe1915002, + 0x0affff93, 0xe1b01001, 0x4affff91, 0xe2433001, + 0xe0922002, 0xe0b11001, 0x5afffffb, 0xeaffff8c, + 0xe2f35901, 0x01925081, 0x0affff89, 0xe2944802, + 0x1a000001, 0xe1914002, 0x1afff93e, 0xe3a014ca, + 0xe3b02100, 0xe2e23902, 0xeafff93a, 0xbe974377, + 0xcc30f9e6, 0x00004003, 0x96f3e4b2, 0xc8e37cbc, + 0x00004006, 0xbeee77e2, 0xb5423cf3, 0x00004007, + 0xd0927880, 0xf5c2170b, 0x00004007, 0xa43601f1, + 0x5c3e6196, 0x00004006, 0xb25dedaf, 0x30f3242c, + 0x00003ffe, 0xa270bb27, 0x61c93957, 0x00004002, + 0x9ec1654d, 0x36d4f820, 0x00004004, 0xe4d539b0, + 0x56a451ad, 0x00004004, 0xdaf2ad41, 0xd05311c4, + 0x00004003, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xc90fdaa2, 0x2168c235, 0x00003fff, + 0xc90fdaa2, 0x2168c235, 0x00004000, 0x00000000, + 0xc90fdaa2, 0x2168c235, 0x00003fff, 0xe3190080, + 0x1affed19, 0xe2096807, 0xe08c6626, 0xe896000f, + 0xe1b04d23, 0xe28f7000, 0x1afff193, 0x1886000f, + 0xe2000102, 0xe183b000, 0xe1a0a002, 0xe1a08001, + 0xe1b06e09, 0x4afff6c9, 0xe08c6c26, 0xe896000f, + 0xe1b04d23, 0xe28f7000, 0x1afff187, 0x1886000f, + 0xe1a0700b, 0xe3cbb102, 0xe1b04883, 0x12944802, + 0x11b0588b, 0x12955802, 0x192c4281, 0x1bffef0b, + 0x1a00004e, 0xe1b04883, 0x1a000010, 0xe1915002, + 0x1a00000a, 0xe1b0588b, 0x0198600a, 0x0a00001f, + 0xe2955802, 0x1a000016, 0xe198600a, 0x0a000014, + 0xe1a01008, 0xe1a0200a, 0xe1a0300b, 0xeafff8e1, + 0xe0922002, 0xe0b11001, 0xe2433001, 0x5afffffb, + 0xe1b0588b, 0x1a000019, 0xe198600a, 0x1a000013, + 0xe2944802, 0x1a000001, 0xe1916002, 0x1afff8d5, + 0xe1a04000, 0xe1a05007, 0xe28f0fbd, 0xe890000e, + 0xea00008c, 0xe1a04000, 0xe1a05007, 0xe3a00000, + 0xe3a01000, 0xe3a02000, 0xe3a03000, 0xea00007d, + 0xe3a014cb, 0xe3b02100, 0xe2e23902, 0xeafff8c5, + 0xe09aa00a, 0xe0b88008, 0xe24bb001, 0x5afffffb, + 0xe2956802, 0x12946802, 0x1affffca, 0xe2946802, + 0x1a000006, 0xe1916002, 0x1afff8ba, 0xe2956802, + 0x1affffe2, 0xe198600a, 0x03a014cb, 0x0afff8b5, + 0xe198600a, 0x0affffe2, 0xe1a01008, 0xe1a0200a, + 0xe1a0300b, 0xeafff8af, 0xe3190080, 0x1affecba, + 0xe1b07e09, 0x4afff671, 0xe08c8c27, 0xe898000f, + 0xe1b04d23, 0xe28f7000, 0x1afff133, 0x1888000f, + 0xe1b04883, 0x12944802, 0x0a000060, 0xe92c4281, + 0xe3b00100, 0xe2f34901, 0xdbffeeb0, 0xd3a04002, + 0xc3a04000, 0xe28f9d06, 0xe8b90d00, 0xe153000b, + 0x01510008, 0x0152000a, 0xc2844001, 0xe92c0010, + 0xda00000d, 0xe92c000f, 0xe8990d00, 0xebffedad, + 0xe8bc0d80, 0xe92c000f, 0xe3a00000, 0xe8b9000e, + 0xebffee51, 0xe3a08102, 0xe3b0a100, 0xe2eab901, + 0xebffeded, 0xe8bc0d80, 0xebffeea0, 0xe3a04901, + 0xe2444021, 0xe1530004, 0xba00002c, 0xe92c000f, + 0xebffee41, 0xe92c000f, 0xe28f9f49, 0xe8b90d00, + 0xebffed98, 0xe89c0d80, 0xebffee3f, 0xe8b90d00, + 0xebffed94, 0xe89c0d80, 0xebffee3b, 0xe8b90d00, + 0xebffed90, 0xe89c0d80, 0xebffee37, 0xe8b90d00, + 0xebffed8c, 0xe89c0d80, 0xe92c000f, 0xe3a00102, + 0xe8b9000e, 0xebffee30, 0xe8b90d00, 0xebffedce, + 0xe28c7010, 0xe8970d80, 0xebffee2b, 0xe8b90d00, + 0xebffedc9, 0xe28c7010, 0xe8970d80, 0xebffee26, + 0xe8b90d00, 0xebffedc4, 0xe28c7010, 0xe8970d80, + 0xebffee21, 0xe8bc0d80, 0xe28cc010, 0xebffee73, + 0xe89c0d80, 0xebffee1c, 0xe8bc0d80, 0xebffed6e, + 0xe28f90dc, 0xe8bc0010, 0xe0200f04, 0xe0899204, + 0xe8990d00, 0xebffed6b, 0xe8bc4230, 0xe3190601, + 0x10200004, 0x1afffc3b, 0xe3150102, 0x0a000005, + 0xe92c4010, 0xe2200102, 0xe24f7d0d, 0xe8970d00, + 0xebffed60, 0xe8bc4010, 0xe0200004, 0xeafffc31, + 0xe3530000, 0x0afffc2f, 0xe1914002, 0x1afff83d, + 0xe28f009c, 0xe890000e, 0xeafffc2a, 0x8930a2f4, + 0xf66ab18a, 0x00003ffd, 0xddb3d742, 0xc265539e, + 0x00003fff, 0xf0624f0a, 0x56388310, 0x00004002, + 0xee505190, 0x6d1eb4e8, 0x00004004, 0xac509020, + 0x5b6d243b, 0x00004005, 0xa443e5e6, 0x24ad4b90, + 0x00004004, 0xd66bd6cd, 0x8c3de934, 0x00003ffe, + 0x87e9fae4, 0x6b531a29, 0x00004002, 0xa40bfdcf, + 0x15e65691, 0x00004003, 0xdb053288, 0x30e70eb4, + 0x00004002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x860a91c1, 0x6b9b2c23, 0x00003ffe, + 0x00000000, 0xc90fdaa2, 0x2168c235, 0x00003fff, + 0x00000000, 0x860a91c1, 0x6b9b2c23, 0x00003fff, + 0xe92d5001, 0xe24fc05c, 0xe24ccc50, 0xe3a00807, + 0xe58c0080, 0xe8bd9001, 0xe1a00000, 0xe3100001, + 0x128f0e15, 0x1a00000a, 0xe3100004, 0x128f0f47, + 0x1a000007, 0xe3100002, 0x128f00e0, 0x1a000004, + 0xe3100008, 0x128f00a8, 0x1a000001, 0xe28f0070, + 0xeaffffff, 0xe28f101c, 0xe14fb000, 0xe8bd07f8, + 0xe8a107f8, 0xe8bd07f8, 0xe24aa004, 0xe8a10ff8, + 0xe28f1000, 0xef000071, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00002278, + 0xffffffff, 0x80000204, 0x616f6c46, 0x676e6974, + 0x696f5020, 0x4520746e, 0x70656378, 0x6e6f6974, + 0x49203a20, 0x6178656e, 0x52207463, 0x6c757365, + 0x00000074, 0x80000203, 0x616f6c46, 0x676e6974, + 0x696f5020, 0x4520746e, 0x70656378, 0x6e6f6974, + 0x55203a20, 0x7265646e, 0x776f6c66, 0x00000000, + 0x80000202, 0x616f6c46, 0x676e6974, 0x696f5020, + 0x4520746e, 0x70656378, 0x6e6f6974, 0x44203a20, + 0x64697669, 0x79422065, 0x72655a20, 0x0000006f, + 0x80000201, 0x616f6c46, 0x676e6974, 0x696f5020, + 0x4520746e, 0x70656378, 0x6e6f6974, 0x4f203a20, + 0x66726576, 0x00776f6c, 0x80000200, 0x616f6c46, + 0x676e6974, 0x696f5020, 0x4520746e, 0x70656378, + 0x6e6f6974, 0x49203a20, 0x6c61766e, 0x4f206469, + 0x61726570, 0x6e6f6974, 0x00000000, 0xfefefeff, 0 +}; + +unsigned long fpesize = 0x00005300;
armfpe.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: armos.c =================================================================== --- armos.c (nonexistent) +++ armos.c (revision 816) @@ -0,0 +1,948 @@ +/* armos.c -- ARMulator OS interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* This file contains a model of Demon, ARM Ltd's Debug Monitor, + including all the SWI's required to support the C library. The code in + it is not really for the faint-hearted (especially the abort handling + code), but it is a complete example. Defining NOOS will disable all the + fun, and definign VAILDATE will define SWI 1 to enter SVC mode, and SWI + 0x11 to halt the emulator. */ + +#include "config.h" +#include "ansidecl.h" + +#include +#include +#include +#include +#include "targ-vals.h" + +#ifndef TARGET_O_BINARY +#define TARGET_O_BINARY 0 +#endif + +#ifdef HAVE_UNISTD_H +#include /* For SEEK_SET etc. */ +#endif + +#ifdef __riscos +extern int _fisatty (FILE *); +#define isatty_(f) _fisatty(f) +#else +#ifdef __ZTC__ +#include +#define isatty_(f) isatty((f)->_file) +#else +#ifdef macintosh +#include +#define isatty_(f) (~ioctl ((f)->_file, FIOINTERACTIVE, NULL)) +#else +#define isatty_(f) isatty (fileno (f)) +#endif +#endif +#endif + +#include "armdefs.h" +#include "armos.h" +#include "armemu.h" + +#ifndef NOOS +#ifndef VALIDATE +/* #ifndef ASIM */ +#include "armfpe.h" +/* #endif */ +#endif +#endif + +/* For RDIError_BreakpointReached. */ +#include "dbg_rdi.h" + +#include "gdb/callback.h" +extern host_callback *sim_callback; + +extern unsigned ARMul_OSInit (ARMul_State *); +extern void ARMul_OSExit (ARMul_State *); +extern unsigned ARMul_OSHandleSWI (ARMul_State *, ARMword); +extern unsigned ARMul_OSException (ARMul_State *, ARMword, ARMword); +extern ARMword ARMul_OSLastErrorP (ARMul_State *); +extern ARMword ARMul_Debug (ARMul_State *, ARMword, ARMword); + +#define BUFFERSIZE 4096 +#ifndef FOPEN_MAX +#define FOPEN_MAX 64 +#endif +#define UNIQUETEMPS 256 +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +/* OS private Information. */ + +struct OSblock +{ + ARMword Time0; + ARMword ErrorP; + ARMword ErrorNo; + FILE *FileTable[FOPEN_MAX]; + char FileFlags[FOPEN_MAX]; + char *tempnames[UNIQUETEMPS]; +}; + +#define NOOP 0 +#define BINARY 1 +#define READOP 2 +#define WRITEOP 4 + +#ifdef macintosh +#define FIXCRLF(t,c) ((t & BINARY) ? \ + c : \ + ((c == '\n' || c == '\r' ) ? (c ^ 7) : c) \ + ) +#else +#define FIXCRLF(t,c) c +#endif + +/* Bit mask of enabled SWI implementations. */ +unsigned int swi_mask = -1; + + +static ARMword softvectorcode[] = +{ + /* Installed instructions: + swi tidyexception + event; + mov lr, pc; + ldmia fp, {fp, pc}; + swi generateexception + event. */ + 0xef000090, 0xe1a0e00f, 0xe89b8800, 0xef000080, /* Reset */ + 0xef000091, 0xe1a0e00f, 0xe89b8800, 0xef000081, /* Undef */ + 0xef000092, 0xe1a0e00f, 0xe89b8800, 0xef000082, /* SWI */ + 0xef000093, 0xe1a0e00f, 0xe89b8800, 0xef000083, /* Prefetch abort */ + 0xef000094, 0xe1a0e00f, 0xe89b8800, 0xef000084, /* Data abort */ + 0xef000095, 0xe1a0e00f, 0xe89b8800, 0xef000085, /* Address exception */ + 0xef000096, 0xe1a0e00f, 0xe89b8800, 0xef000086, /* IRQ */ + 0xef000097, 0xe1a0e00f, 0xe89b8800, 0xef000087, /* FIQ */ + 0xef000098, 0xe1a0e00f, 0xe89b8800, 0xef000088, /* Error */ + 0xe1a0f00e /* Default handler */ +}; + +/* Time for the Operating System to initialise itself. */ + +unsigned +ARMul_OSInit (ARMul_State * state) +{ +#ifndef NOOS +#ifndef VALIDATE + ARMword instr, i, j; + struct OSblock *OSptr = (struct OSblock *) state->OSptr; + + if (state->OSptr == NULL) + { + state->OSptr = (unsigned char *) malloc (sizeof (struct OSblock)); + if (state->OSptr == NULL) + { + perror ("OS Memory"); + exit (15); + } + } + + OSptr = (struct OSblock *) state->OSptr; + OSptr->ErrorP = 0; + state->Reg[13] = ADDRSUPERSTACK; /* Set up a stack for the current mode... */ + ARMul_SetReg (state, SVC32MODE, 13, ADDRSUPERSTACK);/* ...and for supervisor mode... */ + ARMul_SetReg (state, ABORT32MODE, 13, ADDRSUPERSTACK);/* ...and for abort 32 mode... */ + ARMul_SetReg (state, UNDEF32MODE, 13, ADDRSUPERSTACK);/* ...and for undef 32 mode... */ + ARMul_SetReg (state, SYSTEMMODE, 13, ADDRSUPERSTACK);/* ...and for system mode. */ + instr = 0xe59ff000 | (ADDRSOFTVECTORS - 8); /* Load pc from soft vector */ + + for (i = ARMul_ResetV; i <= ARMFIQV; i += 4) + /* Write hardware vectors. */ + ARMul_WriteWord (state, i, instr); + + SWI_vector_installed = 0; + + for (i = ARMul_ResetV; i <= ARMFIQV + 4; i += 4) + { + ARMul_WriteWord (state, ADDRSOFTVECTORS + i, SOFTVECTORCODE + i * 4); + ARMul_WriteWord (state, ADDRSOFHANDLERS + 2 * i + 4L, + SOFTVECTORCODE + sizeof (softvectorcode) - 4L); + } + + for (i = 0; i < sizeof (softvectorcode); i += 4) + ARMul_WriteWord (state, SOFTVECTORCODE + i, softvectorcode[i / 4]); + + for (i = 0; i < FOPEN_MAX; i++) + OSptr->FileTable[i] = NULL; + + for (i = 0; i < UNIQUETEMPS; i++) + OSptr->tempnames[i] = NULL; + + ARMul_ConsolePrint (state, ", Demon 1.01"); + +/* #ifndef ASIM */ + + /* Install FPE. */ + for (i = 0; i < fpesize; i += 4) + /* Copy the code. */ + ARMul_WriteWord (state, FPESTART + i, fpecode[i >> 2]); + + /* Scan backwards from the end of the code. */ + for (i = FPESTART + fpesize;; i -= 4) + { + /* When we reach the marker value, break out of + the loop, leaving i pointing at the maker. */ + if ((j = ARMul_ReadWord (state, i)) == 0xffffffff) + break; + + /* If necessary, reverse the error strings. */ + if (state->bigendSig && j < 0x80000000) + { + /* It's part of the string so swap it. */ + j = ((j >> 0x18) & 0x000000ff) | + ((j >> 0x08) & 0x0000ff00) | + ((j << 0x08) & 0x00ff0000) | ((j << 0x18) & 0xff000000); + ARMul_WriteWord (state, i, j); + } + } + + /* Copy old illegal instr vector. */ + ARMul_WriteWord (state, FPEOLDVECT, ARMul_ReadWord (state, ARMUndefinedInstrV)); + /* Install new vector. */ + ARMul_WriteWord (state, ARMUndefinedInstrV, FPENEWVECT (ARMul_ReadWord (state, i - 4))); + ARMul_ConsolePrint (state, ", FPE"); + +/* #endif ASIM */ +#endif /* VALIDATE */ +#endif /* NOOS */ + + /* Intel do not want DEMON SWI support. */ + if (state->is_XScale) + swi_mask = SWI_MASK_ANGEL; + + return TRUE; +} + +void +ARMul_OSExit (ARMul_State * state) +{ + free ((char *) state->OSptr); +} + + +/* Return the last Operating System Error. */ + +ARMword ARMul_OSLastErrorP (ARMul_State * state) +{ + return ((struct OSblock *) state->OSptr)->ErrorP; +} + +static int translate_open_mode[] = +{ + TARGET_O_RDONLY, /* "r" */ + TARGET_O_RDONLY + TARGET_O_BINARY, /* "rb" */ + TARGET_O_RDWR, /* "r+" */ + TARGET_O_RDWR + TARGET_O_BINARY, /* "r+b" */ + TARGET_O_WRONLY + TARGET_O_CREAT + TARGET_O_TRUNC, /* "w" */ + TARGET_O_WRONLY + TARGET_O_BINARY + TARGET_O_CREAT + TARGET_O_TRUNC, /* "wb" */ + TARGET_O_RDWR + TARGET_O_CREAT + TARGET_O_TRUNC, /* "w+" */ + TARGET_O_RDWR + TARGET_O_BINARY + TARGET_O_CREAT + TARGET_O_TRUNC, /* "w+b" */ + TARGET_O_WRONLY + TARGET_O_APPEND + TARGET_O_CREAT, /* "a" */ + TARGET_O_WRONLY + TARGET_O_BINARY + TARGET_O_APPEND + TARGET_O_CREAT, /* "ab" */ + TARGET_O_RDWR + TARGET_O_APPEND + TARGET_O_CREAT, /* "a+" */ + TARGET_O_RDWR + TARGET_O_BINARY + TARGET_O_APPEND + TARGET_O_CREAT /* "a+b" */ +}; + +static void +SWIWrite0 (ARMul_State * state, ARMword addr) +{ + ARMword temp; + struct OSblock *OSptr = (struct OSblock *) state->OSptr; + + while ((temp = ARMul_SafeReadByte (state, addr++)) != 0) + { + char buffer = temp; + /* Note - we cannot just cast 'temp' to a (char *) here, + since on a big-endian host the byte value will end + up in the wrong place and a nul character will be printed. */ + (void) sim_callback->write_stdout (sim_callback, & buffer, 1); + } + + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); +} + +static void +WriteCommandLineTo (ARMul_State * state, ARMword addr) +{ + ARMword temp; + char *cptr = state->CommandLine; + + if (cptr == NULL) + cptr = "\0"; + do + { + temp = (ARMword) * cptr++; + ARMul_SafeWriteByte (state, addr++, temp); + } + while (temp != 0); +} + +static int +ReadFileName (ARMul_State * state, char *buf, ARMword src, size_t n) +{ + struct OSblock *OSptr = (struct OSblock *) state->OSptr; + char *p = buf; + + while (n--) + if ((*p++ = ARMul_SafeReadByte (state, src++)) == '\0') + return 0; + OSptr->ErrorNo = cb_host_to_target_errno (sim_callback, ENAMETOOLONG); + state->Reg[0] = -1; + return -1; +} + +static void +SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags) +{ + struct OSblock *OSptr = (struct OSblock *) state->OSptr; + char buf[PATH_MAX]; + int flags; + + if (ReadFileName (state, buf, name, sizeof buf) == -1) + return; + + /* Now we need to decode the Demon open mode. */ + flags = translate_open_mode[SWIflags]; + + /* Filename ":tt" is special: it denotes stdin/out. */ + if (strcmp (buf, ":tt") == 0) + { + if (flags == TARGET_O_RDONLY) /* opening tty "r" */ + state->Reg[0] = 0; /* stdin */ + else + state->Reg[0] = 1; /* stdout */ + } + else + { + state->Reg[0] = sim_callback->open (sim_callback, buf, flags); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + } +} + +static void +SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len) +{ + struct OSblock *OSptr = (struct OSblock *) state->OSptr; + int res; + int i; + char *local = malloc (len); + + if (local == NULL) + { + sim_callback->printf_filtered + (sim_callback, + "sim: Unable to read 0x%ulx bytes - out of memory\n", + len); + return; + } + + res = sim_callback->read (sim_callback, f, local, len); + if (res > 0) + for (i = 0; i < res; i++) + ARMul_SafeWriteByte (state, ptr + i, local[i]); + + free (local); + state->Reg[0] = res == -1 ? -1 : len - res; + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); +} + +static void +SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len) +{ + struct OSblock *OSptr = (struct OSblock *) state->OSptr; + int res; + ARMword i; + char *local = malloc (len); + + if (local == NULL) + { + sim_callback->printf_filtered + (sim_callback, + "sim: Unable to write 0x%lx bytes - out of memory\n", + (long) len); + return; + } + + for (i = 0; i < len; i++) + local[i] = ARMul_SafeReadByte (state, ptr + i); + + res = sim_callback->write (sim_callback, f, local, len); + state->Reg[0] = res == -1 ? -1 : len - res; + free (local); + + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); +} + +static void +SWIflen (ARMul_State * state, ARMword fh) +{ + struct OSblock *OSptr = (struct OSblock *) state->OSptr; + ARMword addr; + + if (fh > FOPEN_MAX) + { + OSptr->ErrorNo = EBADF; + state->Reg[0] = -1L; + return; + } + + addr = sim_callback->lseek (sim_callback, fh, 0, SEEK_CUR); + + state->Reg[0] = sim_callback->lseek (sim_callback, fh, 0L, SEEK_END); + (void) sim_callback->lseek (sim_callback, fh, addr, SEEK_SET); + + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); +} + +static void +SWIremove (ARMul_State * state, ARMword path) +{ + char buf[PATH_MAX]; + + if (ReadFileName (state, buf, path, sizeof buf) != -1) + { + struct OSblock *OSptr = (struct OSblock *) state->OSptr; + state->Reg[0] = sim_callback->unlink (sim_callback, buf); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + } +} + +static void +SWIrename (ARMul_State * state, ARMword old, ARMword new) +{ + char oldbuf[PATH_MAX], newbuf[PATH_MAX]; + + if (ReadFileName (state, oldbuf, old, sizeof oldbuf) != -1 + && ReadFileName (state, newbuf, new, sizeof newbuf) != -1) + { + struct OSblock *OSptr = (struct OSblock *) state->OSptr; + state->Reg[0] = sim_callback->rename (sim_callback, oldbuf, newbuf); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + } +} + +/* The emulator calls this routine when a SWI instruction is encuntered. + The parameter passed is the SWI number (lower 24 bits of the instruction). */ + +unsigned +ARMul_OSHandleSWI (ARMul_State * state, ARMword number) +{ + struct OSblock * OSptr = (struct OSblock *) state->OSptr; + int unhandled = FALSE; + + switch (number) + { + case SWI_Read: + if (swi_mask & SWI_MASK_DEMON) + SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]); + else + unhandled = TRUE; + break; + + case SWI_Write: + if (swi_mask & SWI_MASK_DEMON) + SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]); + else + unhandled = TRUE; + break; + + case SWI_Open: + if (swi_mask & SWI_MASK_DEMON) + SWIopen (state, state->Reg[0], state->Reg[1]); + else + unhandled = TRUE; + break; + + case SWI_Clock: + if (swi_mask & SWI_MASK_DEMON) + { + /* Return number of centi-seconds. */ + state->Reg[0] = +#ifdef CLOCKS_PER_SEC + (CLOCKS_PER_SEC >= 100) + ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100)) + : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC); +#else + /* Presume unix... clock() returns microseconds. */ + (ARMword) (clock () / 10000); +#endif + OSptr->ErrorNo = errno; + } + else + unhandled = TRUE; + break; + + case SWI_Time: + if (swi_mask & SWI_MASK_DEMON) + { + state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + } + else + unhandled = TRUE; + break; + + case SWI_Close: + if (swi_mask & SWI_MASK_DEMON) + { + state->Reg[0] = sim_callback->close (sim_callback, state->Reg[0]); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + } + else + unhandled = TRUE; + break; + + case SWI_Flen: + if (swi_mask & SWI_MASK_DEMON) + SWIflen (state, state->Reg[0]); + else + unhandled = TRUE; + break; + + case SWI_Exit: + if (swi_mask & SWI_MASK_DEMON) + state->Emulate = FALSE; + else + unhandled = TRUE; + break; + + case SWI_Seek: + if (swi_mask & SWI_MASK_DEMON) + { + /* We must return non-zero for failure. */ + state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, state->Reg[0], state->Reg[1], SEEK_SET); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + } + else + unhandled = TRUE; + break; + + case SWI_WriteC: + if (swi_mask & SWI_MASK_DEMON) + { + char tmp = state->Reg[0]; + (void) sim_callback->write_stdout (sim_callback, &tmp, 1); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + } + else + unhandled = TRUE; + break; + + case SWI_Write0: + if (swi_mask & SWI_MASK_DEMON) + SWIWrite0 (state, state->Reg[0]); + else + unhandled = TRUE; + break; + + case SWI_GetErrno: + if (swi_mask & SWI_MASK_DEMON) + state->Reg[0] = OSptr->ErrorNo; + else + unhandled = TRUE; + break; + + case SWI_GetEnv: + if (swi_mask & SWI_MASK_DEMON) + { + state->Reg[0] = ADDRCMDLINE; + if (state->MemSize) + state->Reg[1] = state->MemSize; + else + state->Reg[1] = ADDRUSERSTACK; + + WriteCommandLineTo (state, state->Reg[0]); + } + else + unhandled = TRUE; + break; + + case SWI_Breakpoint: + state->EndCondition = RDIError_BreakpointReached; + state->Emulate = FALSE; + break; + + case SWI_Remove: + if (swi_mask & SWI_MASK_DEMON) + SWIremove (state, state->Reg[0]); + else + unhandled = TRUE; + break; + + case SWI_Rename: + if (swi_mask & SWI_MASK_DEMON) + SWIrename (state, state->Reg[0], state->Reg[1]); + else + unhandled = TRUE; + break; + + case SWI_IsTTY: + if (swi_mask & SWI_MASK_DEMON) + { + state->Reg[0] = sim_callback->isatty (sim_callback, state->Reg[0]); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + } + else + unhandled = TRUE; + break; + + /* Handle Angel SWIs as well as Demon ones. */ + case AngelSWI_ARM: + case AngelSWI_Thumb: + if (swi_mask & SWI_MASK_ANGEL) + { + ARMword addr; + ARMword temp; + + /* R1 is almost always a parameter block. */ + addr = state->Reg[1]; + /* R0 is a reason code. */ + switch (state->Reg[0]) + { + case -1: + /* This can happen when a SWI is interrupted (eg receiving a + ctrl-C whilst processing SWIRead()). The SWI will complete + returning -1 in r0 to the caller. If GDB is then used to + resume the system call the reason code will now be -1. */ + return TRUE; + + /* Unimplemented reason codes. */ + case AngelSWI_Reason_ReadC: + case AngelSWI_Reason_TmpNam: + case AngelSWI_Reason_System: + case AngelSWI_Reason_EnterSVC: + default: + state->Emulate = FALSE; + return FALSE; + + case AngelSWI_Reason_Clock: + /* Return number of centi-seconds. */ + state->Reg[0] = +#ifdef CLOCKS_PER_SEC + (CLOCKS_PER_SEC >= 100) + ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100)) + : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC); +#else + /* Presume unix... clock() returns microseconds. */ + (ARMword) (clock () / 10000); +#endif + OSptr->ErrorNo = errno; + break; + + case AngelSWI_Reason_Time: + state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + break; + + case AngelSWI_Reason_WriteC: + { + char tmp = ARMul_SafeReadByte (state, addr); + (void) sim_callback->write_stdout (sim_callback, &tmp, 1); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + break; + } + + case AngelSWI_Reason_Write0: + SWIWrite0 (state, addr); + break; + + case AngelSWI_Reason_Close: + state->Reg[0] = sim_callback->close (sim_callback, ARMul_ReadWord (state, addr)); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + break; + + case AngelSWI_Reason_Seek: + state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, ARMul_ReadWord (state, addr), + ARMul_ReadWord (state, addr + 4), + SEEK_SET); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + break; + + case AngelSWI_Reason_FLen: + SWIflen (state, ARMul_ReadWord (state, addr)); + break; + + case AngelSWI_Reason_GetCmdLine: + WriteCommandLineTo (state, ARMul_ReadWord (state, addr)); + break; + + case AngelSWI_Reason_HeapInfo: + /* R1 is a pointer to a pointer. */ + addr = ARMul_ReadWord (state, addr); + + /* Pick up the right memory limit. */ + if (state->MemSize) + temp = state->MemSize; + else + temp = ADDRUSERSTACK; + + ARMul_WriteWord (state, addr, 0); /* Heap base. */ + ARMul_WriteWord (state, addr + 4, temp); /* Heap limit. */ + ARMul_WriteWord (state, addr + 8, temp); /* Stack base. */ + ARMul_WriteWord (state, addr + 12, temp); /* Stack limit. */ + break; + + case AngelSWI_Reason_ReportException: + if (state->Reg[1] == ADP_Stopped_ApplicationExit) + state->Reg[0] = 0; + else + state->Reg[0] = -1; + state->Emulate = FALSE; + break; + + case ADP_Stopped_ApplicationExit: + state->Reg[0] = 0; + state->Emulate = FALSE; + break; + + case ADP_Stopped_RunTimeError: + state->Reg[0] = -1; + state->Emulate = FALSE; + break; + + case AngelSWI_Reason_Errno: + state->Reg[0] = OSptr->ErrorNo; + break; + + case AngelSWI_Reason_Open: + SWIopen (state, + ARMul_ReadWord (state, addr), + ARMul_ReadWord (state, addr + 4)); + break; + + case AngelSWI_Reason_Read: + SWIread (state, + ARMul_ReadWord (state, addr), + ARMul_ReadWord (state, addr + 4), + ARMul_ReadWord (state, addr + 8)); + break; + + case AngelSWI_Reason_Write: + SWIwrite (state, + ARMul_ReadWord (state, addr), + ARMul_ReadWord (state, addr + 4), + ARMul_ReadWord (state, addr + 8)); + break; + + case AngelSWI_Reason_IsTTY: + state->Reg[0] = sim_callback->isatty (sim_callback, + ARMul_ReadWord (state, addr)); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + break; + + case AngelSWI_Reason_Remove: + SWIremove (state, + ARMul_ReadWord (state, addr)); + + case AngelSWI_Reason_Rename: + SWIrename (state, + ARMul_ReadWord (state, addr), + ARMul_ReadWord (state, addr + 4)); + } + } + else + unhandled = TRUE; + break; + + /* The following SWIs are generated by the softvectorcode[] + installed by default by the simulator. */ + case 0x91: /* Undefined Instruction. */ + { + ARMword addr = state->RegBank[UNDEFBANK][14] - 4; + + sim_callback->printf_filtered + (sim_callback, "sim: exception: Unhandled Instruction '0x%08x' at 0x%08x. Stopping.\n", + ARMul_ReadWord (state, addr), addr); + state->EndCondition = RDIError_SoftwareInterrupt; + state->Emulate = FALSE; + return FALSE; + } + + case 0x90: /* Reset. */ + case 0x92: /* SWI. */ + /* These two can be safely ignored. */ + break; + + case 0x93: /* Prefetch Abort. */ + case 0x94: /* Data Abort. */ + case 0x95: /* Address Exception. */ + case 0x96: /* IRQ. */ + case 0x97: /* FIQ. */ + case 0x98: /* Error. */ + unhandled = TRUE; + break; + + case -1: + /* This can happen when a SWI is interrupted (eg receiving a + ctrl-C whilst processing SWIRead()). The SWI will complete + returning -1 in r0 to the caller. If GDB is then used to + resume the system call the reason code will now be -1. */ + return TRUE; + + case 0x180001: /* RedBoot's Syscall SWI in ARM mode. */ + if (swi_mask & SWI_MASK_REDBOOT) + { + switch (state->Reg[0]) + { + /* These numbers are defined in libgloss/syscall.h + but the simulator should not be dependend upon + libgloss being installed. */ + case 1: /* Exit. */ + state->Emulate = FALSE; + /* Copy exit code into r0. */ + state->Reg[0] = state->Reg[1]; + break; + + case 2: /* Open. */ + SWIopen (state, state->Reg[1], state->Reg[2]); + break; + + case 3: /* Close. */ + state->Reg[0] = sim_callback->close (sim_callback, state->Reg[1]); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + break; + + case 4: /* Read. */ + SWIread (state, state->Reg[1], state->Reg[2], state->Reg[3]); + break; + + case 5: /* Write. */ + SWIwrite (state, state->Reg[1], state->Reg[2], state->Reg[3]); + break; + + case 6: /* Lseek. */ + state->Reg[0] = sim_callback->lseek (sim_callback, + state->Reg[1], + state->Reg[2], + state->Reg[3]); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + break; + + case 17: /* Utime. */ + state->Reg[0] = (ARMword) sim_callback->time (sim_callback, + (long *) state->Reg[1]); + OSptr->ErrorNo = sim_callback->get_errno (sim_callback); + break; + + case 7: /* Unlink. */ + case 8: /* Getpid. */ + case 9: /* Kill. */ + case 10: /* Fstat. */ + case 11: /* Sbrk. */ + case 12: /* Argvlen. */ + case 13: /* Argv. */ + case 14: /* ChDir. */ + case 15: /* Stat. */ + case 16: /* Chmod. */ + case 18: /* Time. */ + sim_callback->printf_filtered + (sim_callback, + "sim: unhandled RedBoot syscall `%d' encountered - " + "returning ENOSYS\n", + state->Reg[0]); + state->Reg[0] = -1; + OSptr->ErrorNo = cb_host_to_target_errno + (sim_callback, ENOSYS); + break; + case 1001: /* Meminfo. */ + { + ARMword totmem = state->Reg[1], + topmem = state->Reg[2]; + ARMword stack = state->MemSize > 0 + ? state->MemSize : ADDRUSERSTACK; + if (totmem != 0) + ARMul_WriteWord (state, totmem, stack); + if (topmem != 0) + ARMul_WriteWord (state, topmem, stack); + state->Reg[0] = 0; + break; + } + + default: + sim_callback->printf_filtered + (sim_callback, + "sim: unknown RedBoot syscall '%d' encountered - ignoring\n", + state->Reg[0]); + return FALSE; + } + break; + } + + default: + unhandled = TRUE; + } + + if (unhandled) + { + if (SWI_vector_installed) + { + ARMword cpsr; + ARMword i_size; + + cpsr = ARMul_GetCPSR (state); + i_size = INSN_SIZE; + + ARMul_SetSPSR (state, SVC32MODE, cpsr); + + cpsr &= ~0xbf; + cpsr |= SVC32MODE | 0x80; + ARMul_SetCPSR (state, cpsr); + + state->RegBank[SVCBANK][14] = state->Reg[14] = state->Reg[15] - i_size; + state->NextInstr = RESUME; + state->Reg[15] = state->pc = ARMSWIV; + FLUSHPIPE; + } + else + { + sim_callback->printf_filtered + (sim_callback, + "sim: unknown SWI encountered - %x - ignoring\n", + number); + return FALSE; + } + } + + return TRUE; +} + +#ifndef NOOS +#ifndef ASIM + +/* The emulator calls this routine when an Exception occurs. The second + parameter is the address of the relevant exception vector. Returning + FALSE from this routine causes the trap to be taken, TRUE causes it to + be ignored (so set state->Emulate to FALSE!). */ + +unsigned +ARMul_OSException (ARMul_State * state ATTRIBUTE_UNUSED, + ARMword vector ATTRIBUTE_UNUSED, + ARMword pc ATTRIBUTE_UNUSED) +{ + return FALSE; +} + +#endif +#endif /* NOOS */
armos.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.ac =================================================================== --- configure.ac (nonexistent) +++ configure.ac (revision 816) @@ -0,0 +1,18 @@ +dnl Process this file with autoconf to produce a configure script. +AC_PREREQ(2.59)dnl +AC_INIT(Makefile.in) +AC_CONFIG_HEADER(config.h:config.in) + +sinclude(../common/aclocal.m4) + +# Bugs in autoconf 2.59 break the call to SIM_AC_COMMON, hack around +# it by inlining the macro's contents. +sinclude(../common/common.m4) + +AC_CHECK_HEADERS(unistd.h stdint.h) + +COPRO="armcopro.o maverick.o iwmmxt.o" + +AC_SUBST(COPRO) + +SIM_AC_OUTPUT
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: armcopro.c =================================================================== --- armcopro.c (nonexistent) +++ armcopro.c (revision 816) @@ -0,0 +1,1449 @@ +/* armcopro.c -- co-processor interface: ARM6 Instruction Emulator. + Copyright (C) 1994, 2000 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "armdefs.h" +#include "armos.h" +#include "armemu.h" +#include "ansidecl.h" +#include "iwmmxt.h" + +/* Dummy Co-processors. */ + +static unsigned +NoCoPro3R (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned a ATTRIBUTE_UNUSED, + ARMword b ATTRIBUTE_UNUSED) +{ + return ARMul_CANT; +} + +static unsigned +NoCoPro4R (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned a ATTRIBUTE_UNUSED, + ARMword b ATTRIBUTE_UNUSED, + ARMword c ATTRIBUTE_UNUSED) +{ + return ARMul_CANT; +} + +static unsigned +NoCoPro4W (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned a ATTRIBUTE_UNUSED, + ARMword b ATTRIBUTE_UNUSED, + ARMword * c ATTRIBUTE_UNUSED) +{ + return ARMul_CANT; +} + +/* The XScale Co-processors. */ + +/* Coprocessor 15: System Control. */ +static void write_cp14_reg (unsigned, ARMword); +static ARMword read_cp14_reg (unsigned); + +/* There are two sets of registers for copro 15. + One set is available when opcode_2 is 0 and + the other set when opcode_2 >= 1. */ +static ARMword XScale_cp15_opcode_2_is_0_Regs[16]; +static ARMword XScale_cp15_opcode_2_is_not_0_Regs[16]; +/* There are also a set of breakpoint registers + which are accessed via CRm instead of opcode_2. */ +static ARMword XScale_cp15_DBR1; +static ARMword XScale_cp15_DBCON; +static ARMword XScale_cp15_IBCR0; +static ARMword XScale_cp15_IBCR1; + +static unsigned +XScale_cp15_init (ARMul_State * state ATTRIBUTE_UNUSED) +{ + int i; + + for (i = 16; i--;) + { + XScale_cp15_opcode_2_is_0_Regs[i] = 0; + XScale_cp15_opcode_2_is_not_0_Regs[i] = 0; + } + + /* Initialise the processor ID. */ + XScale_cp15_opcode_2_is_0_Regs[0] = 0x69052000; + + /* Initialise the cache type. */ + XScale_cp15_opcode_2_is_not_0_Regs[0] = 0x0B1AA1AA; + + /* Initialise the ARM Control Register. */ + XScale_cp15_opcode_2_is_0_Regs[1] = 0x00000078; +} + +/* Check an access to a register. */ + +static unsigned +check_cp15_access (ARMul_State * state, + unsigned reg, + unsigned CRm, + unsigned opcode_1, + unsigned opcode_2) +{ + /* Do not allow access to these register in USER mode. */ + if (state->Mode == USER26MODE || state->Mode == USER32MODE) + return ARMul_CANT; + + /* Opcode_1should be zero. */ + if (opcode_1 != 0) + return ARMul_CANT; + + /* Different register have different access requirements. */ + switch (reg) + { + case 0: + case 1: + /* CRm must be 0. Opcode_2 can be anything. */ + if (CRm != 0) + return ARMul_CANT; + break; + case 2: + case 3: + /* CRm must be 0. Opcode_2 must be zero. */ + if ((CRm != 0) || (opcode_2 != 0)) + return ARMul_CANT; + break; + case 4: + /* Access not allowed. */ + return ARMul_CANT; + case 5: + case 6: + /* Opcode_2 must be zero. CRm must be 0. */ + if ((CRm != 0) || (opcode_2 != 0)) + return ARMul_CANT; + break; + case 7: + /* Permissable combinations: + Opcode_2 CRm + 0 5 + 0 6 + 0 7 + 1 5 + 1 6 + 1 10 + 4 10 + 5 2 + 6 5 */ + switch (opcode_2) + { + default: return ARMul_CANT; + case 6: if (CRm != 5) return ARMul_CANT; break; + case 5: if (CRm != 2) return ARMul_CANT; break; + case 4: if (CRm != 10) return ARMul_CANT; break; + case 1: if ((CRm != 5) && (CRm != 6) && (CRm != 10)) return ARMul_CANT; break; + case 0: if ((CRm < 5) || (CRm > 7)) return ARMul_CANT; break; + } + break; + + case 8: + /* Permissable combinations: + Opcode_2 CRm + 0 5 + 0 6 + 0 7 + 1 5 + 1 6 */ + if (opcode_2 > 1) + return ARMul_CANT; + if ((CRm < 5) || (CRm > 7)) + return ARMul_CANT; + if (opcode_2 == 1 && CRm == 7) + return ARMul_CANT; + break; + case 9: + /* Opcode_2 must be zero or one. CRm must be 1 or 2. */ + if ( ((CRm != 0) && (CRm != 1)) + || ((opcode_2 != 1) && (opcode_2 != 2))) + return ARMul_CANT; + break; + case 10: + /* Opcode_2 must be zero or one. CRm must be 4 or 8. */ + if ( ((CRm != 0) && (CRm != 1)) + || ((opcode_2 != 4) && (opcode_2 != 8))) + return ARMul_CANT; + break; + case 11: + /* Access not allowed. */ + return ARMul_CANT; + case 12: + /* Access not allowed. */ + return ARMul_CANT; + case 13: + /* Opcode_2 must be zero. CRm must be 0. */ + if ((CRm != 0) || (opcode_2 != 0)) + return ARMul_CANT; + break; + case 14: + /* Opcode_2 must be 0. CRm must be 0, 3, 4, 8 or 9. */ + if (opcode_2 != 0) + return ARMul_CANT; + + if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8) && (CRm != 9)) + return ARMul_CANT; + break; + case 15: + /* Opcode_2 must be zero. CRm must be 1. */ + if ((CRm != 1) || (opcode_2 != 0)) + return ARMul_CANT; + break; + default: + /* Should never happen. */ + return ARMul_CANT; + } + + return ARMul_DONE; +} + +/* Store a value into one of coprocessor 15's registers. */ + +static void +write_cp15_reg (ARMul_State * state, + unsigned reg, + unsigned opcode_2, + unsigned CRm, + ARMword value) +{ + if (opcode_2) + { + switch (reg) + { + case 0: /* Cache Type. */ + /* Writes are not allowed. */ + return; + + case 1: /* Auxillary Control. */ + /* Only BITS (5, 4) and BITS (1, 0) can be written. */ + value &= 0x33; + break; + + default: + return; + } + + XScale_cp15_opcode_2_is_not_0_Regs [reg] = value; + } + else + { + switch (reg) + { + case 0: /* ID. */ + /* Writes are not allowed. */ + return; + + case 1: /* ARM Control. */ + /* Only BITS (13, 11), BITS (9, 7) and BITS (2, 0) can be written. + BITS (31, 14) and BIT (10) write as zero, BITS (6, 3) write as one. */ + value &= 0x00003b87; + value |= 0x00000078; + + /* Change the endianness if necessary. */ + if ((value & ARMul_CP15_R1_ENDIAN) != + (XScale_cp15_opcode_2_is_0_Regs [reg] & ARMul_CP15_R1_ENDIAN)) + { + state->bigendSig = value & ARMul_CP15_R1_ENDIAN; + /* Force ARMulator to notice these now. */ + state->Emulate = CHANGEMODE; + } + break; + + case 2: /* Translation Table Base. */ + /* Only BITS (31, 14) can be written. */ + value &= 0xffffc000; + break; + + case 3: /* Domain Access Control. */ + /* All bits writable. */ + break; + + case 5: /* Fault Status Register. */ + /* BITS (10, 9) and BITS (7, 0) can be written. */ + value &= 0x000006ff; + break; + + case 6: /* Fault Address Register. */ + /* All bits writable. */ + break; + + case 7: /* Cache Functions. */ + case 8: /* TLB Operations. */ + case 10: /* TLB Lock Down. */ + /* Ignore writes. */ + return; + + case 9: /* Data Cache Lock. */ + /* Only BIT (0) can be written. */ + value &= 0x1; + break; + + case 13: /* Process ID. */ + /* Only BITS (31, 25) are writable. */ + value &= 0xfe000000; + break; + + case 14: /* DBR0, DBR1, DBCON, IBCR0, IBCR1 */ + /* All bits can be written. Which register is accessed is + dependent upon CRm. */ + switch (CRm) + { + case 0: /* DBR0 */ + break; + case 3: /* DBR1 */ + XScale_cp15_DBR1 = value; + break; + case 4: /* DBCON */ + XScale_cp15_DBCON = value; + break; + case 8: /* IBCR0 */ + XScale_cp15_IBCR0 = value; + break; + case 9: /* IBCR1 */ + XScale_cp15_IBCR1 = value; + break; + default: + return; + } + break; + + case 15: /* Coprpcessor Access Register. */ + /* Access is only valid if CRm == 1. */ + if (CRm != 1) + return; + + /* Only BITS (13, 0) may be written. */ + value &= 0x00003fff; + break; + + default: + return; + } + + XScale_cp15_opcode_2_is_0_Regs [reg] = value; + } + + return; +} + +/* Return the value in a cp15 register. */ + +ARMword +read_cp15_reg (unsigned reg, unsigned opcode_2, unsigned CRm) +{ + if (opcode_2 == 0) + { + if (reg == 15 && CRm != 1) + return 0; + + if (reg == 14) + { + switch (CRm) + { + case 3: return XScale_cp15_DBR1; + case 4: return XScale_cp15_DBCON; + case 8: return XScale_cp15_IBCR0; + case 9: return XScale_cp15_IBCR1; + default: + break; + } + } + + return XScale_cp15_opcode_2_is_0_Regs [reg]; + } + else + return XScale_cp15_opcode_2_is_not_0_Regs [reg]; + + return 0; +} + +static unsigned +XScale_cp15_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data) +{ + unsigned reg = BITS (12, 15); + unsigned result; + + result = check_cp15_access (state, reg, 0, 0, 0); + + if (result == ARMul_DONE && type == ARMul_DATA) + write_cp15_reg (state, reg, 0, 0, data); + + return result; +} + +static unsigned +XScale_cp15_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data) +{ + unsigned reg = BITS (12, 15); + unsigned result; + + result = check_cp15_access (state, reg, 0, 0, 0); + + if (result == ARMul_DONE && type == ARMul_DATA) + * data = read_cp15_reg (reg, 0, 0); + + return result; +} + +static unsigned +XScale_cp15_MRC (ARMul_State * state, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword * value) +{ + unsigned opcode_2 = BITS (5, 7); + unsigned CRm = BITS (0, 3); + unsigned reg = BITS (16, 19); + unsigned result; + + result = check_cp15_access (state, reg, CRm, BITS (21, 23), opcode_2); + + if (result == ARMul_DONE) + * value = read_cp15_reg (reg, opcode_2, CRm); + + return result; +} + +static unsigned +XScale_cp15_MCR (ARMul_State * state, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword value) +{ + unsigned opcode_2 = BITS (5, 7); + unsigned CRm = BITS (0, 3); + unsigned reg = BITS (16, 19); + unsigned result; + + result = check_cp15_access (state, reg, CRm, BITS (21, 23), opcode_2); + + if (result == ARMul_DONE) + write_cp15_reg (state, reg, opcode_2, CRm, value); + + return result; +} + +static unsigned +XScale_cp15_read_reg (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned reg, + ARMword * value) +{ + /* FIXME: Not sure what to do about the alternative register set + here. For now default to just accessing CRm == 0 registers. */ + * value = read_cp15_reg (reg, 0, 0); + + return TRUE; +} + +static unsigned +XScale_cp15_write_reg (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned reg, + ARMword value) +{ + /* FIXME: Not sure what to do about the alternative register set + here. For now default to just accessing CRm == 0 registers. */ + write_cp15_reg (state, reg, 0, 0, value); + + return TRUE; +} + +/* Check for special XScale memory access features. */ + +void +XScale_check_memacc (ARMul_State * state, ARMword * address, int store) +{ + ARMword dbcon, r0, r1; + int e1, e0; + + if (!state->is_XScale) + return; + + /* Check for PID-ification. + XXX BTB access support will require this test failing. */ + r0 = (read_cp15_reg (13, 0, 0) & 0xfe000000); + if (r0 && (* address & 0xfe000000) == 0) + * address |= r0; + + /* Check alignment fault enable/disable. */ + if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN) && (* address & 3)) + { + /* Set the FSR and FAR. + Do not use XScale_set_fsr_far as this checks the DCSR register. */ + write_cp15_reg (state, 5, 0, 0, ARMul_CP15_R5_MMU_EXCPT); + write_cp15_reg (state, 6, 0, 0, * address); + + ARMul_Abort (state, ARMul_DataAbortV); + } + + if (XScale_debug_moe (state, -1)) + return; + + /* Check the data breakpoint registers. */ + dbcon = read_cp15_reg (14, 0, 4); + r0 = read_cp15_reg (14, 0, 0); + r1 = read_cp15_reg (14, 0, 3); + e0 = dbcon & ARMul_CP15_DBCON_E0; + + if (dbcon & ARMul_CP15_DBCON_M) + { + /* r1 is a inverse mask. */ + if (e0 != 0 && ((store && e0 != 3) || (!store && e0 != 1)) + && ((* address & ~r1) == (r0 & ~r1))) + { + XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB); + ARMul_OSHandleSWI (state, SWI_Breakpoint); + } + } + else + { + if (e0 != 0 && ((store && e0 != 3) || (!store && e0 != 1)) + && ((* address & ~3) == (r0 & ~3))) + { + XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB); + ARMul_OSHandleSWI (state, SWI_Breakpoint); + } + + e1 = (dbcon & ARMul_CP15_DBCON_E1) >> 2; + if (e1 != 0 && ((store && e1 != 3) || (!store && e1 != 1)) + && ((* address & ~3) == (r1 & ~3))) + { + XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB); + ARMul_OSHandleSWI (state, SWI_Breakpoint); + } + } +} + +/* Set the XScale FSR and FAR registers. */ + +void +XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword far) +{ + if (!state->is_XScale || (read_cp14_reg (10) & (1UL << 31)) == 0) + return; + + write_cp15_reg (state, 5, 0, 0, fsr); + write_cp15_reg (state, 6, 0, 0, far); +} + +/* Set the XScale debug `method of entry' if it is enabled. */ + +int +XScale_debug_moe (ARMul_State * state, int moe) +{ + ARMword value; + + if (!state->is_XScale) + return 1; + + value = read_cp14_reg (10); + if (value & (1UL << 31)) + { + if (moe != -1) + { + value &= ~0x1c; + value |= moe; + + write_cp14_reg (10, value); + } + return 1; + } + return 0; +} + +/* Coprocessor 13: Interrupt Controller and Bus Controller. */ + +/* There are two sets of registers for copro 13. + One set (of three registers) is available when CRm is 0 + and the other set (of six registers) when CRm is 1. */ + +static ARMword XScale_cp13_CR0_Regs[16]; +static ARMword XScale_cp13_CR1_Regs[16]; + +static unsigned +XScale_cp13_init (ARMul_State * state ATTRIBUTE_UNUSED) +{ + int i; + + for (i = 16; i--;) + { + XScale_cp13_CR0_Regs[i] = 0; + XScale_cp13_CR1_Regs[i] = 0; + } +} + +/* Check an access to a register. */ + +static unsigned +check_cp13_access (ARMul_State * state, + unsigned reg, + unsigned CRm, + unsigned opcode_1, + unsigned opcode_2) +{ + /* Do not allow access to these registers in USER mode. */ + if (state->Mode == USER26MODE || state->Mode == USER32MODE) + return ARMul_CANT; + + /* The opcodes should be zero. */ + if ((opcode_1 != 0) || (opcode_2 != 0)) + return ARMul_CANT; + + /* Do not allow access to these register if bit + 13 of coprocessor 15's register 15 is zero. */ + if (! CP_ACCESS_ALLOWED (state, 13)) + return ARMul_CANT; + + /* Registers 0, 4 and 8 are defined when CRm == 0. + Registers 0, 1, 4, 5, 6, 7, 8 are defined when CRm == 1. + For all other CRm values undefined behaviour results. */ + if (CRm == 0) + { + if (reg == 0 || reg == 4 || reg == 8) + return ARMul_DONE; + } + else if (CRm == 1) + { + if (reg == 0 || reg == 1 || (reg >= 4 && reg <= 8)) + return ARMul_DONE; + } + + return ARMul_CANT; +} + +/* Store a value into one of coprocessor 13's registers. */ + +static void +write_cp13_reg (unsigned reg, unsigned CRm, ARMword value) +{ + switch (CRm) + { + case 0: + switch (reg) + { + case 0: /* INTCTL */ + /* Only BITS (3:0) can be written. */ + value &= 0xf; + break; + + case 4: /* INTSRC */ + /* No bits may be written. */ + return; + + case 8: /* INTSTR */ + /* Only BITS (1:0) can be written. */ + value &= 0x3; + break; + + default: + /* Should not happen. Ignore any writes to unimplemented registers. */ + return; + } + + XScale_cp13_CR0_Regs [reg] = value; + break; + + case 1: + switch (reg) + { + case 0: /* BCUCTL */ + /* Only BITS (30:28) and BITS (3:0) can be written. + BIT(31) is write ignored. */ + value &= 0x7000000f; + value |= XScale_cp13_CR1_Regs[0] & (1UL << 31); + break; + + case 1: /* BCUMOD */ + /* Only bit 0 is accecssible. */ + value &= 1; + value |= XScale_cp13_CR1_Regs[1] & ~ 1; + break; + + case 4: /* ELOG0 */ + case 5: /* ELOG1 */ + case 6: /* ECAR0 */ + case 7: /* ECAR1 */ + /* No bits can be written. */ + return; + + case 8: /* ECTST */ + /* Only BITS (7:0) can be written. */ + value &= 0xff; + break; + + default: + /* Should not happen. Ignore any writes to unimplemented registers. */ + return; + } + + XScale_cp13_CR1_Regs [reg] = value; + break; + + default: + /* Should not happen. */ + break; + } + + return; +} + +/* Return the value in a cp13 register. */ + +static ARMword +read_cp13_reg (unsigned reg, unsigned CRm) +{ + if (CRm == 0) + return XScale_cp13_CR0_Regs [reg]; + else if (CRm == 1) + return XScale_cp13_CR1_Regs [reg]; + + return 0; +} + +static unsigned +XScale_cp13_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data) +{ + unsigned reg = BITS (12, 15); + unsigned result; + + result = check_cp13_access (state, reg, 0, 0, 0); + + if (result == ARMul_DONE && type == ARMul_DATA) + write_cp13_reg (reg, 0, data); + + return result; +} + +static unsigned +XScale_cp13_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data) +{ + unsigned reg = BITS (12, 15); + unsigned result; + + result = check_cp13_access (state, reg, 0, 0, 0); + + if (result == ARMul_DONE && type == ARMul_DATA) + * data = read_cp13_reg (reg, 0); + + return result; +} + +static unsigned +XScale_cp13_MRC (ARMul_State * state, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword * value) +{ + unsigned CRm = BITS (0, 3); + unsigned reg = BITS (16, 19); + unsigned result; + + result = check_cp13_access (state, reg, CRm, BITS (21, 23), BITS (5, 7)); + + if (result == ARMul_DONE) + * value = read_cp13_reg (reg, CRm); + + return result; +} + +static unsigned +XScale_cp13_MCR (ARMul_State * state, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword value) +{ + unsigned CRm = BITS (0, 3); + unsigned reg = BITS (16, 19); + unsigned result; + + result = check_cp13_access (state, reg, CRm, BITS (21, 23), BITS (5, 7)); + + if (result == ARMul_DONE) + write_cp13_reg (reg, CRm, value); + + return result; +} + +static unsigned +XScale_cp13_read_reg (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned reg, + ARMword * value) +{ + /* FIXME: Not sure what to do about the alternative register set + here. For now default to just accessing CRm == 0 registers. */ + * value = read_cp13_reg (reg, 0); + + return TRUE; +} + +static unsigned +XScale_cp13_write_reg (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned reg, + ARMword value) +{ + /* FIXME: Not sure what to do about the alternative register set + here. For now default to just accessing CRm == 0 registers. */ + write_cp13_reg (reg, 0, value); + + return TRUE; +} + +/* Coprocessor 14: Performance Monitoring, Clock and Power management, + Software Debug. */ + +static ARMword XScale_cp14_Regs[16]; + +static unsigned +XScale_cp14_init (ARMul_State * state ATTRIBUTE_UNUSED) +{ + int i; + + for (i = 16; i--;) + XScale_cp14_Regs[i] = 0; +} + +/* Check an access to a register. */ + +static unsigned +check_cp14_access (ARMul_State * state, + unsigned reg, + unsigned CRm, + unsigned opcode1, + unsigned opcode2) +{ + /* Not allowed to access these register in USER mode. */ + if (state->Mode == USER26MODE || state->Mode == USER32MODE) + return ARMul_CANT; + + /* CRm should be zero. */ + if (CRm != 0) + return ARMul_CANT; + + /* OPcodes should be zero. */ + if (opcode1 != 0 || opcode2 != 0) + return ARMul_CANT; + + /* Accessing registers 4 or 5 has unpredicatable results. */ + if (reg >= 4 && reg <= 5) + return ARMul_CANT; + + return ARMul_DONE; +} + +/* Store a value into one of coprocessor 14's registers. */ + +static void +write_cp14_reg (unsigned reg, ARMword value) +{ + switch (reg) + { + case 0: /* PMNC */ + /* Only BITS (27:12), BITS (10:8) and BITS (6:0) can be written. */ + value &= 0x0ffff77f; + + /* Reset the clock counter if necessary. */ + if (value & ARMul_CP14_R0_CLKRST) + XScale_cp14_Regs [1] = 0; + break; + + case 4: + case 5: + /* We should not normally reach this code. The debugger interface + can bypass the normal checks though, so it could happen. */ + value = 0; + break; + + case 6: /* CCLKCFG */ + /* Only BITS (3:0) can be written. */ + value &= 0xf; + break; + + case 7: /* PWRMODE */ + /* Although BITS (1:0) can be written with non-zero values, this would + have the side effect of putting the processor to sleep. Thus in + order for the register to be read again, it would have to go into + ACTIVE mode, which means that any read will see these bits as zero. + + Rather than trying to implement complex reset-to-zero-upon-read logic + we just override the write value with zero. */ + value = 0; + break; + + case 10: /* DCSR */ + /* Only BITS (31:30), BITS (23:22), BITS (20:16) and BITS (5:0) can + be written. */ + value &= 0xc0df003f; + break; + + case 11: /* TBREG */ + /* No writes are permitted. */ + value = 0; + break; + + case 14: /* TXRXCTRL */ + /* Only BITS (31:30) can be written. */ + value &= 0xc0000000; + break; + + default: + /* All bits can be written. */ + break; + } + + XScale_cp14_Regs [reg] = value; +} + +/* Return the value in a cp14 register. Not a static function since + it is used by the code to emulate the BKPT instruction in armemu.c. */ + +ARMword +read_cp14_reg (unsigned reg) +{ + return XScale_cp14_Regs [reg]; +} + +static unsigned +XScale_cp14_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data) +{ + unsigned reg = BITS (12, 15); + unsigned result; + + result = check_cp14_access (state, reg, 0, 0, 0); + + if (result == ARMul_DONE && type == ARMul_DATA) + write_cp14_reg (reg, data); + + return result; +} + +static unsigned +XScale_cp14_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data) +{ + unsigned reg = BITS (12, 15); + unsigned result; + + result = check_cp14_access (state, reg, 0, 0, 0); + + if (result == ARMul_DONE && type == ARMul_DATA) + * data = read_cp14_reg (reg); + + return result; +} + +static unsigned +XScale_cp14_MRC +( + ARMul_State * state, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword * value +) +{ + unsigned reg = BITS (16, 19); + unsigned result; + + result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7)); + + if (result == ARMul_DONE) + * value = read_cp14_reg (reg); + + return result; +} + +static unsigned +XScale_cp14_MCR +( + ARMul_State * state, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword value +) +{ + unsigned reg = BITS (16, 19); + unsigned result; + + result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7)); + + if (result == ARMul_DONE) + write_cp14_reg (reg, value); + + return result; +} + +static unsigned +XScale_cp14_read_reg +( + ARMul_State * state ATTRIBUTE_UNUSED, + unsigned reg, + ARMword * value +) +{ + * value = read_cp14_reg (reg); + + return TRUE; +} + +static unsigned +XScale_cp14_write_reg +( + ARMul_State * state ATTRIBUTE_UNUSED, + unsigned reg, + ARMword value +) +{ + write_cp14_reg (reg, value); + + return TRUE; +} + +/* Here's ARMulator's MMU definition. A few things to note: + 1) It has eight registers, but only two are defined. + 2) You can only access its registers with MCR and MRC. + 3) MMU Register 0 (ID) returns 0x41440110 + 4) Register 1 only has 4 bits defined. Bits 0 to 3 are unused, bit 4 + controls 32/26 bit program space, bit 5 controls 32/26 bit data space, + bit 6 controls late abort timimg and bit 7 controls big/little endian. */ + +static ARMword MMUReg[8]; + +static unsigned +MMUInit (ARMul_State * state) +{ + MMUReg[1] = state->prog32Sig << 4 | + state->data32Sig << 5 | state->lateabtSig << 6 | state->bigendSig << 7; + + ARMul_ConsolePrint (state, ", MMU present"); + + return TRUE; +} + +static unsigned +MMUMRC (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword * value) +{ + int reg = BITS (16, 19) & 7; + + if (reg == 0) + *value = 0x41440110; + else + *value = MMUReg[reg]; + + return ARMul_DONE; +} + +static unsigned +MMUMCR (ARMul_State * state, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword value) +{ + int reg = BITS (16, 19) & 7; + + MMUReg[reg] = value; + + if (reg == 1) + { + ARMword p,d,l,b; + + p = state->prog32Sig; + d = state->data32Sig; + l = state->lateabtSig; + b = state->bigendSig; + + state->prog32Sig = value >> 4 & 1; + state->data32Sig = value >> 5 & 1; + state->lateabtSig = value >> 6 & 1; + state->bigendSig = value >> 7 & 1; + + if ( p != state->prog32Sig + || d != state->data32Sig + || l != state->lateabtSig + || b != state->bigendSig) + /* Force ARMulator to notice these now. */ + state->Emulate = CHANGEMODE; + } + + return ARMul_DONE; +} + +static unsigned +MMURead (ARMul_State * state ATTRIBUTE_UNUSED, unsigned reg, ARMword * value) +{ + if (reg == 0) + *value = 0x41440110; + else if (reg < 8) + *value = MMUReg[reg]; + + return TRUE; +} + +static unsigned +MMUWrite (ARMul_State * state, unsigned reg, ARMword value) +{ + if (reg < 8) + MMUReg[reg] = value; + + if (reg == 1) + { + ARMword p,d,l,b; + + p = state->prog32Sig; + d = state->data32Sig; + l = state->lateabtSig; + b = state->bigendSig; + + state->prog32Sig = value >> 4 & 1; + state->data32Sig = value >> 5 & 1; + state->lateabtSig = value >> 6 & 1; + state->bigendSig = value >> 7 & 1; + + if ( p != state->prog32Sig + || d != state->data32Sig + || l != state->lateabtSig + || b != state->bigendSig) + /* Force ARMulator to notice these now. */ + state->Emulate = CHANGEMODE; + } + + return TRUE; +} + + +/* What follows is the Validation Suite Coprocessor. It uses two + co-processor numbers (4 and 5) and has the follwing functionality. + Sixteen registers. Both co-processor nuimbers can be used in an MCR + and MRC to access these registers. CP 4 can LDC and STC to and from + the registers. CP 4 and CP 5 CDP 0 will busy wait for the number of + cycles specified by a CP register. CP 5 CDP 1 issues a FIQ after a + number of cycles (specified in a CP register), CDP 2 issues an IRQW + in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5 + stores a 32 bit time value in a CP register (actually it's the total + number of N, S, I, C and F cyles). */ + +static ARMword ValReg[16]; + +static unsigned +ValLDC (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type, + ARMword instr, + ARMword data) +{ + static unsigned words; + + if (type != ARMul_DATA) + words = 0; + else + { + ValReg[BITS (12, 15)] = data; + + if (BIT (22)) + /* It's a long access, get two words. */ + if (words++ != 4) + return ARMul_INC; + } + + return ARMul_DONE; +} + +static unsigned +ValSTC (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type, + ARMword instr, + ARMword * data) +{ + static unsigned words; + + if (type != ARMul_DATA) + words = 0; + else + { + * data = ValReg[BITS (12, 15)]; + + if (BIT (22)) + /* It's a long access, get two words. */ + if (words++ != 4) + return ARMul_INC; + } + + return ARMul_DONE; +} + +static unsigned +ValMRC (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword * value) +{ + *value = ValReg[BITS (16, 19)]; + + return ARMul_DONE; +} + +static unsigned +ValMCR (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword value) +{ + ValReg[BITS (16, 19)] = value; + + return ARMul_DONE; +} + +static unsigned +ValCDP (ARMul_State * state, unsigned type, ARMword instr) +{ + static unsigned long finish = 0; + + if (BITS (20, 23) != 0) + return ARMul_CANT; + + if (type == ARMul_FIRST) + { + ARMword howlong; + + howlong = ValReg[BITS (0, 3)]; + + /* First cycle of a busy wait. */ + finish = ARMul_Time (state) + howlong; + + return howlong == 0 ? ARMul_DONE : ARMul_BUSY; + } + else if (type == ARMul_BUSY) + { + if (ARMul_Time (state) >= finish) + return ARMul_DONE; + else + return ARMul_BUSY; + } + + return ARMul_CANT; +} + +static unsigned +DoAFIQ (ARMul_State * state) +{ + state->NfiqSig = LOW; + state->Exception++; + return 0; +} + +static unsigned +DoAIRQ (ARMul_State * state) +{ + state->NirqSig = LOW; + state->Exception++; + return 0; +} + +static unsigned +IntCDP (ARMul_State * state, unsigned type, ARMword instr) +{ + static unsigned long finish; + ARMword howlong; + + howlong = ValReg[BITS (0, 3)]; + + switch ((int) BITS (20, 23)) + { + case 0: + if (type == ARMul_FIRST) + { + /* First cycle of a busy wait. */ + finish = ARMul_Time (state) + howlong; + + return howlong == 0 ? ARMul_DONE : ARMul_BUSY; + } + else if (type == ARMul_BUSY) + { + if (ARMul_Time (state) >= finish) + return ARMul_DONE; + else + return ARMul_BUSY; + } + return ARMul_DONE; + + case 1: + if (howlong == 0) + ARMul_Abort (state, ARMul_FIQV); + else + ARMul_ScheduleEvent (state, howlong, DoAFIQ); + return ARMul_DONE; + + case 2: + if (howlong == 0) + ARMul_Abort (state, ARMul_IRQV); + else + ARMul_ScheduleEvent (state, howlong, DoAIRQ); + return ARMul_DONE; + + case 3: + state->NfiqSig = HIGH; + state->Exception--; + return ARMul_DONE; + + case 4: + state->NirqSig = HIGH; + state->Exception--; + return ARMul_DONE; + + case 5: + ValReg[BITS (0, 3)] = ARMul_Time (state); + return ARMul_DONE; + } + + return ARMul_CANT; +} + +/* Install co-processor instruction handlers in this routine. */ + +unsigned +ARMul_CoProInit (ARMul_State * state) +{ + unsigned int i; + + /* Initialise tham all first. */ + for (i = 0; i < 16; i++) + ARMul_CoProDetach (state, i); + + /* Install CoPro Instruction handlers here. + The format is: + ARMul_CoProAttach (state, CP Number, Init routine, Exit routine + LDC routine, STC routine, MRC routine, MCR routine, + CDP routine, Read Reg routine, Write Reg routine). */ + if (state->is_ep9312) + { + ARMul_CoProAttach (state, 4, NULL, NULL, DSPLDC4, DSPSTC4, + DSPMRC4, DSPMCR4, DSPCDP4, NULL, NULL); + ARMul_CoProAttach (state, 5, NULL, NULL, DSPLDC5, DSPSTC5, + DSPMRC5, DSPMCR5, DSPCDP5, NULL, NULL); + ARMul_CoProAttach (state, 6, NULL, NULL, NULL, NULL, + DSPMRC6, DSPMCR6, DSPCDP6, NULL, NULL); + } + else + { + ARMul_CoProAttach (state, 4, NULL, NULL, ValLDC, ValSTC, + ValMRC, ValMCR, ValCDP, NULL, NULL); + + ARMul_CoProAttach (state, 5, NULL, NULL, NULL, NULL, + ValMRC, ValMCR, IntCDP, NULL, NULL); + } + + if (state->is_XScale) + { + ARMul_CoProAttach (state, 13, XScale_cp13_init, NULL, + XScale_cp13_LDC, XScale_cp13_STC, XScale_cp13_MRC, + XScale_cp13_MCR, NULL, XScale_cp13_read_reg, + XScale_cp13_write_reg); + + ARMul_CoProAttach (state, 14, XScale_cp14_init, NULL, + XScale_cp14_LDC, XScale_cp14_STC, XScale_cp14_MRC, + XScale_cp14_MCR, NULL, XScale_cp14_read_reg, + XScale_cp14_write_reg); + + ARMul_CoProAttach (state, 15, XScale_cp15_init, NULL, + NULL, NULL, XScale_cp15_MRC, XScale_cp15_MCR, + NULL, XScale_cp15_read_reg, XScale_cp15_write_reg); + } + else + { + ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL, + MMUMRC, MMUMCR, NULL, MMURead, MMUWrite); + } + + if (state->is_iWMMXt) + { + ARMul_CoProAttach (state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC, + NULL, NULL, IwmmxtCDP, NULL, NULL); + + ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL, + IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, NULL); + } + + /* No handlers below here. */ + + /* Call all the initialisation routines. */ + for (i = 0; i < 16; i++) + if (state->CPInit[i]) + (state->CPInit[i]) (state); + + return TRUE; +} + +/* Install co-processor finalisation routines in this routine. */ + +void +ARMul_CoProExit (ARMul_State * state) +{ + register unsigned i; + + for (i = 0; i < 16; i++) + if (state->CPExit[i]) + (state->CPExit[i]) (state); + + for (i = 0; i < 16; i++) /* Detach all handlers. */ + ARMul_CoProDetach (state, i); +} + +/* Routines to hook Co-processors into ARMulator. */ + +void +ARMul_CoProAttach (ARMul_State * state, + unsigned number, + ARMul_CPInits * init, + ARMul_CPExits * exit, + ARMul_LDCs * ldc, + ARMul_STCs * stc, + ARMul_MRCs * mrc, + ARMul_MCRs * mcr, + ARMul_CDPs * cdp, + ARMul_CPReads * read, + ARMul_CPWrites * write) +{ + if (init != NULL) + state->CPInit[number] = init; + if (exit != NULL) + state->CPExit[number] = exit; + if (ldc != NULL) + state->LDC[number] = ldc; + if (stc != NULL) + state->STC[number] = stc; + if (mrc != NULL) + state->MRC[number] = mrc; + if (mcr != NULL) + state->MCR[number] = mcr; + if (cdp != NULL) + state->CDP[number] = cdp; + if (read != NULL) + state->CPRead[number] = read; + if (write != NULL) + state->CPWrite[number] = write; +} + +void +ARMul_CoProDetach (ARMul_State * state, unsigned number) +{ + ARMul_CoProAttach (state, number, NULL, NULL, + NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R, + NoCoPro3R, NULL, NULL); + + state->CPInit[number] = NULL; + state->CPExit[number] = NULL; + state->CPRead[number] = NULL; + state->CPWrite[number] = NULL; +}
armcopro.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: armvirt.c =================================================================== --- armvirt.c (nonexistent) +++ armvirt.c (revision 816) @@ -0,0 +1,522 @@ +/* armvirt.c -- ARMulator virtual memory interace: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* This file contains a complete ARMulator memory model, modelling a +"virtual memory" system. A much simpler model can be found in armfast.c, +and that model goes faster too, but has a fixed amount of memory. This +model's memory has 64K pages, allocated on demand from a 64K entry page +table. The routines PutWord and GetWord implement this. Pages are never +freed as they might be needed again. A single area of memory may be +defined to generate aborts. */ + +#include "armopts.h" +#include "armos.h" +#include "armdefs.h" +#include "ansidecl.h" + +#ifdef VALIDATE /* for running the validate suite */ +#define TUBE 48 * 1024 * 1024 /* write a char on the screen */ +#define ABORTS 1 +#endif + +/* #define ABORTS */ + +#ifdef ABORTS /* the memory system will abort */ +/* For the old test suite Abort between 32 Kbytes and 32 Mbytes + For the new test suite Abort between 8 Mbytes and 26 Mbytes */ +/* #define LOWABORT 32 * 1024 +#define HIGHABORT 32 * 1024 * 1024 */ +#define LOWABORT 8 * 1024 * 1024 +#define HIGHABORT 26 * 1024 * 1024 + +#endif + +#define NUMPAGES 64 * 1024 +#define PAGESIZE 64 * 1024 +#define PAGEBITS 16 +#define OFFSETBITS 0xffff + +int SWI_vector_installed = FALSE; + +/***************************************************************************\ +* Get a Word from Virtual Memory, maybe allocating the page * +\***************************************************************************/ + +static ARMword +GetWord (ARMul_State * state, ARMword address, int check) +{ + ARMword page; + ARMword offset; + ARMword **pagetable; + ARMword *pageptr; + + if (check && state->is_XScale) + XScale_check_memacc (state, &address, 0); + + page = address >> PAGEBITS; + offset = (address & OFFSETBITS) >> 2; + pagetable = (ARMword **) state->MemDataPtr; + pageptr = *(pagetable + page); + + if (pageptr == NULL) + { + pageptr = (ARMword *) malloc (PAGESIZE); + + if (pageptr == NULL) + { + perror ("ARMulator can't allocate VM page"); + exit (12); + } + + *(pagetable + page) = pageptr; + } + + return *(pageptr + offset); +} + +/***************************************************************************\ +* Put a Word into Virtual Memory, maybe allocating the page * +\***************************************************************************/ + +static void +PutWord (ARMul_State * state, ARMword address, ARMword data, int check) +{ + ARMword page; + ARMword offset; + ARMword **pagetable; + ARMword *pageptr; + + if (check && state->is_XScale) + XScale_check_memacc (state, &address, 1); + + page = address >> PAGEBITS; + offset = (address & OFFSETBITS) >> 2; + pagetable = (ARMword **) state->MemDataPtr; + pageptr = *(pagetable + page); + + if (pageptr == NULL) + { + pageptr = (ARMword *) malloc (PAGESIZE); + if (pageptr == NULL) + { + perror ("ARMulator can't allocate VM page"); + exit (13); + } + + *(pagetable + page) = pageptr; + } + + if (address == 0x8) + SWI_vector_installed = TRUE; + + *(pageptr + offset) = data; +} + +/***************************************************************************\ +* Initialise the memory interface * +\***************************************************************************/ + +unsigned +ARMul_MemoryInit (ARMul_State * state, unsigned long initmemsize) +{ + ARMword **pagetable; + unsigned page; + + if (initmemsize) + state->MemSize = initmemsize; + + pagetable = (ARMword **) malloc (sizeof (ARMword *) * NUMPAGES); + + if (pagetable == NULL) + return FALSE; + + for (page = 0; page < NUMPAGES; page++) + *(pagetable + page) = NULL; + + state->MemDataPtr = (unsigned char *) pagetable; + + ARMul_ConsolePrint (state, ", 4 Gb memory"); + + return TRUE; +} + +/***************************************************************************\ +* Remove the memory interface * +\***************************************************************************/ + +void +ARMul_MemoryExit (ARMul_State * state) +{ + ARMword page; + ARMword **pagetable; + ARMword *pageptr; + + pagetable = (ARMword **) state->MemDataPtr; + for (page = 0; page < NUMPAGES; page++) + { + pageptr = *(pagetable + page); + if (pageptr != NULL) + free ((char *) pageptr); + } + free ((char *) pagetable); + return; +} + +/***************************************************************************\ +* ReLoad Instruction * +\***************************************************************************/ + +ARMword +ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize) +{ +#ifdef ABORTS + if (address >= LOWABORT && address < HIGHABORT) + { + ARMul_PREFETCHABORT (address); + return ARMul_ABORTWORD; + } + else + { + ARMul_CLEARABORT; + } +#endif + + if ((isize == 2) && (address & 0x2)) + { + /* We return the next two halfwords: */ + ARMword lo = GetWord (state, address, FALSE); + ARMword hi = GetWord (state, address + 4, FALSE); + + if (state->bigendSig == HIGH) + return (lo << 16) | (hi >> 16); + else + return ((hi & 0xFFFF) << 16) | (lo >> 16); + } + + return GetWord (state, address, TRUE); +} + +/***************************************************************************\ +* Load Instruction, Sequential Cycle * +\***************************************************************************/ + +ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize) +{ + state->NumScycles++; + +#ifdef HOURGLASS + if ((state->NumScycles & HOURGLASS_RATE) == 0) + { + HOURGLASS; + } +#endif + + return ARMul_ReLoadInstr (state, address, isize); +} + +/***************************************************************************\ +* Load Instruction, Non Sequential Cycle * +\***************************************************************************/ + +ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize) +{ + state->NumNcycles++; + + return ARMul_ReLoadInstr (state, address, isize); +} + +/***************************************************************************\ +* Read Word (but don't tell anyone!) * +\***************************************************************************/ + +ARMword ARMul_ReadWord (ARMul_State * state, ARMword address) +{ +#ifdef ABORTS + if (address >= LOWABORT && address < HIGHABORT) + { + ARMul_DATAABORT (address); + return ARMul_ABORTWORD; + } + else + { + ARMul_CLEARABORT; + } +#endif + + return GetWord (state, address, TRUE); +} + +/***************************************************************************\ +* Load Word, Sequential Cycle * +\***************************************************************************/ + +ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address) +{ + state->NumScycles++; + + return ARMul_ReadWord (state, address); +} + +/***************************************************************************\ +* Load Word, Non Sequential Cycle * +\***************************************************************************/ + +ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address) +{ + state->NumNcycles++; + + return ARMul_ReadWord (state, address); +} + +/***************************************************************************\ +* Load Halfword, (Non Sequential Cycle) * +\***************************************************************************/ + +ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address) +{ + ARMword temp, offset; + + state->NumNcycles++; + + temp = ARMul_ReadWord (state, address); + offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */ + + return (temp >> offset) & 0xffff; +} + +/***************************************************************************\ +* Read Byte (but don't tell anyone!) * +\***************************************************************************/ + +ARMword ARMul_ReadByte (ARMul_State * state, ARMword address) +{ + ARMword temp, offset; + + temp = ARMul_ReadWord (state, address); + offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */ + + return (temp >> offset & 0xffL); +} + +/***************************************************************************\ +* Load Byte, (Non Sequential Cycle) * +\***************************************************************************/ + +ARMword ARMul_LoadByte (ARMul_State * state, ARMword address) +{ + state->NumNcycles++; + + return ARMul_ReadByte (state, address); +} + +/***************************************************************************\ +* Write Word (but don't tell anyone!) * +\***************************************************************************/ + +void +ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data) +{ +#ifdef ABORTS + if (address >= LOWABORT && address < HIGHABORT) + { + ARMul_DATAABORT (address); + return; + } + else + { + ARMul_CLEARABORT; + } +#endif + + PutWord (state, address, data, TRUE); +} + +/***************************************************************************\ +* Store Word, Sequential Cycle * +\***************************************************************************/ + +void +ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data) +{ + state->NumScycles++; + + ARMul_WriteWord (state, address, data); +} + +/***************************************************************************\ +* Store Word, Non Sequential Cycle * +\***************************************************************************/ + +void +ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data) +{ + state->NumNcycles++; + + ARMul_WriteWord (state, address, data); +} + +/***************************************************************************\ +* Store HalfWord, (Non Sequential Cycle) * +\***************************************************************************/ + +void +ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp, offset; + + state->NumNcycles++; + +#ifdef VALIDATE + if (address == TUBE) + { + if (data == 4) + state->Emulate = FALSE; + else + (void) putc ((char) data, stderr); /* Write Char */ + return; + } +#endif + + temp = ARMul_ReadWord (state, address); + offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */ + + PutWord (state, address, + (temp & ~(0xffffL << offset)) | ((data & 0xffffL) << offset), + TRUE); +} + +/***************************************************************************\ +* Write Byte (but don't tell anyone!) * +\***************************************************************************/ + +void +ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp, offset; + + temp = ARMul_ReadWord (state, address); + offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */ + + PutWord (state, address, + (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset), + TRUE); +} + +/***************************************************************************\ +* Store Byte, (Non Sequential Cycle) * +\***************************************************************************/ + +void +ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data) +{ + state->NumNcycles++; + +#ifdef VALIDATE + if (address == TUBE) + { + if (data == 4) + state->Emulate = FALSE; + else + (void) putc ((char) data, stderr); /* Write Char */ + return; + } +#endif + + ARMul_WriteByte (state, address, data); +} + +/***************************************************************************\ +* Swap Word, (Two Non Sequential Cycles) * +\***************************************************************************/ + +ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp; + + state->NumNcycles++; + + temp = ARMul_ReadWord (state, address); + + state->NumNcycles++; + + PutWord (state, address, data, TRUE); + + return temp; +} + +/***************************************************************************\ +* Swap Byte, (Two Non Sequential Cycles) * +\***************************************************************************/ + +ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp; + + temp = ARMul_LoadByte (state, address); + ARMul_StoreByte (state, address, data); + + return temp; +} + +/***************************************************************************\ +* Count I Cycles * +\***************************************************************************/ + +void +ARMul_Icycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED) +{ + state->NumIcycles += number; + ARMul_CLEARABORT; +} + +/***************************************************************************\ +* Count C Cycles * +\***************************************************************************/ + +void +ARMul_Ccycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED) +{ + state->NumCcycles += number; + ARMul_CLEARABORT; +} + + +/* Read a byte. Do not check for alignment or access errors. */ + +ARMword +ARMul_SafeReadByte (ARMul_State * state, ARMword address) +{ + ARMword temp, offset; + + temp = GetWord (state, address, FALSE); + offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; + + return (temp >> offset & 0xffL); +} + +void +ARMul_SafeWriteByte (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp, offset; + + temp = GetWord (state, address, FALSE); + offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; + + PutWord (state, address, + (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset), + FALSE); +}
armvirt.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: armos.h =================================================================== --- armos.h (nonexistent) +++ armos.h (revision 816) @@ -0,0 +1,94 @@ +/* armos.h -- ARMulator OS definitions: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Define the initial layout of memory. */ + +#define ADDRSUPERSTACK 0x800L /* Supervisor stack space. */ +#define ADDRUSERSTACK 0x80000L/* Default user stack start. */ +#define ADDRSOFTVECTORS 0x840L /* Soft vectors are here. */ +#define ADDRCMDLINE 0xf00L /* Command line is here after a SWI GetEnv. */ +#define ADDRSOFHANDLERS 0xad0L /* Address and workspace for installed handlers. */ +#define SOFTVECTORCODE 0xb80L /* Default handlers. */ + +/* SWI numbers. */ + +#define SWI_WriteC 0x0 +#define SWI_Write0 0x2 +#define SWI_ReadC 0x4 +#define SWI_CLI 0x5 +#define SWI_GetEnv 0x10 +#define SWI_Exit 0x11 +#define SWI_EnterOS 0x16 + +#define SWI_GetErrno 0x60 +#define SWI_Clock 0x61 +#define SWI_Time 0x63 +#define SWI_Remove 0x64 +#define SWI_Rename 0x65 +#define SWI_Open 0x66 + +#define SWI_Close 0x68 +#define SWI_Write 0x69 +#define SWI_Read 0x6a +#define SWI_Seek 0x6b +#define SWI_Flen 0x6c + +#define SWI_IsTTY 0x6e +#define SWI_TmpNam 0x6f +#define SWI_InstallHandler 0x70 +#define SWI_GenerateError 0x71 + +#define SWI_Breakpoint 0x180000 /* See gdb's tm-arm.h */ + +#define AngelSWI_ARM 0x123456 +#define AngelSWI_Thumb 0xAB + +/* The reason codes: */ +#define AngelSWI_Reason_Open 0x01 +#define AngelSWI_Reason_Close 0x02 +#define AngelSWI_Reason_WriteC 0x03 +#define AngelSWI_Reason_Write0 0x04 +#define AngelSWI_Reason_Write 0x05 +#define AngelSWI_Reason_Read 0x06 +#define AngelSWI_Reason_ReadC 0x07 +#define AngelSWI_Reason_IsTTY 0x09 +#define AngelSWI_Reason_Seek 0x0A +#define AngelSWI_Reason_FLen 0x0C +#define AngelSWI_Reason_TmpNam 0x0D +#define AngelSWI_Reason_Remove 0x0E +#define AngelSWI_Reason_Rename 0x0F +#define AngelSWI_Reason_Clock 0x10 +#define AngelSWI_Reason_Time 0x11 +#define AngelSWI_Reason_System 0x12 +#define AngelSWI_Reason_Errno 0x13 +#define AngelSWI_Reason_GetCmdLine 0x15 +#define AngelSWI_Reason_HeapInfo 0x16 +#define AngelSWI_Reason_EnterSVC 0x17 +#define AngelSWI_Reason_ReportException 0x18 +#define ADP_Stopped_ApplicationExit ((2 << 16) + 38) +#define ADP_Stopped_RunTimeError ((2 << 16) + 35) + +/* Floating Point Emulator address space. */ +#define FPESTART 0x2000L +#define FPEEND 0x8000L +#define FPEOLDVECT FPESTART + 0x100L + 8L * 16L + 4L /* Stack + 8 regs + fpsr. */ +#define FPENEWVECT(addr) 0xea000000L + ((addr) >> 2) - 3L /* Branch from 4 to 0x2400. */ + +extern unsigned long fpecode[]; +extern unsigned long fpesize; + +extern int SWI_vector_installed;
armos.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: COPYING =================================================================== --- COPYING (nonexistent) +++ COPYING (revision 816) @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License.
COPYING 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: dbg_hif.h =================================================================== --- dbg_hif.h (nonexistent) +++ dbg_hif.h (revision 816) @@ -0,0 +1,48 @@ +/* dbg_hif.h -- ARMulator debug interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +typedef void Hif_DbgPrint (void *arg, const char *format, va_list ap); +typedef void Hif_DbgPause (void *arg); + +typedef void Hif_WriteC (void *arg, int c); +typedef int Hif_ReadC (void *arg); +typedef int Hif_Write (void *arg, char const *buffer, int len); +typedef char *Hif_GetS (void *arg, char *buffer, int len); + +typedef void Hif_RDIResetProc (void *arg); + +struct Dbg_HostosInterface +{ + Hif_DbgPrint *dbgprint; + Hif_DbgPause *dbgpause; + void *dbgarg; + + Hif_WriteC *writec; + Hif_ReadC *readc; + Hif_Write *write; + Hif_GetS *gets; + void *hostosarg; + + Hif_RDIResetProc *reset; + void *resetarg; +};
dbg_hif.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: parent.c =================================================================== --- parent.c (nonexistent) +++ parent.c (revision 816) @@ -0,0 +1,481 @@ +/* parent.c -- ARMulator RDP comms code: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/*****************************************************************/ +/* The Parent process continues here... */ +/* It waits on the socket and passes on RDP messages down a pipe */ +/* to the ARMulator RDP to RDI interpreter. */ +/*****************************************************************/ + +#include +#include +#include +#include "time.h" +#include "armdefs.h" +#include "dbg_rdi.h" +#include "communicate.h" + +/* The socket to the debugger */ +extern int debugsock; + +/* The pipes between the two processes */ +extern int mumkid[2]; +extern int kidmum[2]; + +/* A pipe for handling SWI return values that goes straight from the */ +/* parent to the ARMulator host interface, bypassing the child's RDP */ +/* to RDI interpreter */ +extern int DebuggerARMul[2]; + +/* The maximum number of file descriptors */ +extern int nfds; + +/* The child process id. */ +extern pid_t child; + +void +parent () +{ + int i, j, k; + unsigned char message, CPnum, exreturn; + ARMword mask, nbytes, messagetype; + unsigned char c, d; + ARMword x, y; + int virgin = 1; + struct fd_set readfds; + +#ifdef DEBUG + fprintf (stderr, "parent ()...\n"); +#endif + +panic_error: + + if (!virgin) + { +#ifdef DEBUG + fprintf (stderr, "Arghh! What is going on?\n"); +#endif + kill (child, SIGHUP); + MYwrite_char (debugsock, RDP_Reset); + } + + virgin = 0; + + while (1) + { + + /* Wait either for the ARMulator or the debugger */ + + FD_ZERO (&readfds); + FD_SET (kidmum[0], &readfds); /* Wait for messages from ARMulator */ + FD_SET (debugsock, &readfds); /* Wait for messages from debugger */ + +#ifdef DEBUG + fprintf (stderr, "Waiting for ARMulator or debugger... "); +#endif + + while ((i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, 0)) < 0) + { + perror ("select"); + } + +#ifdef DEBUG + fprintf (stderr, "(%d/2)", i); +#endif + + if (FD_ISSET (debugsock, &readfds)) + { +#ifdef DEBUG + fprintf (stderr, "->debugger\n"); +#endif + + /* Inside this rather large if statement with simply pass on a complete + message to the ARMulator. The reason we need to pass messages on one + at a time is that we have to know whether the message is an OSOpReply + or an info(stop), so that we can take different action in those + cases. */ + + if (MYread_char (debugsock, &message)) + goto panic_error; + + switch (message) + { + case RDP_Start: + /* Open and/or Initialise */ +#ifdef DEBUG + fprintf (stderr, "RDP Open\n"); +#endif + if (MYread_char (debugsock, &c)) /* type */ + goto panic_error; + + if (MYread_word (debugsock, &x)) /* memory size */ + goto panic_error; + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], c); + MYwrite_word (mumkid[1], x); + if (c & 0x2) + { + passon (debugsock, mumkid[1], 1); /* speed */ + } + break; + + case RDP_End: + /* Close and Finalise */ +#ifdef DEBUG + fprintf (stderr, "RDP Close\n"); +#endif + MYwrite_char (mumkid[1], message); + break; + + case RDP_Read: + /* Read Memory Address */ +#ifdef DEBUG + fprintf (stderr, "RDP Read Memory\n"); +#endif + MYwrite_char (mumkid[1], message); + if (passon (debugsock, mumkid[1], 4)) + goto panic_error; /* address */ + if (MYread_word (debugsock, &nbytes)) + goto panic_error; /* nbytes */ + MYwrite_word (mumkid[1], nbytes); + break; + + case RDP_Write: + /* Write Memory Address */ +#ifdef DEBUG + fprintf (stderr, "RDP Write Memory\n"); +#endif + if (MYread_word (debugsock, &x)) + goto panic_error; /* address */ + + if (MYread_word (debugsock, &y)) + goto panic_error; /* nbytes */ + + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], x); + MYwrite_word (mumkid[1], y); + passon (debugsock, mumkid[1], y); /* actual data */ + break; + + case RDP_CPUread: + /* Read CPU State */ +#ifdef DEBUG + fprintf (stderr, "RDP Read CPU\n"); +#endif + if (MYread_char (debugsock, &c)) + goto panic_error; /* mode */ + + if (MYread_word (debugsock, &mask)) + goto panic_error; /* mask */ + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], c); + MYwrite_word (mumkid[1], mask); + break; + + case RDP_CPUwrite: + /* Write CPU State */ +#ifdef DEBUG + fprintf (stderr, "RDP Write CPU\n"); +#endif + if (MYread_char (debugsock, &c)) + goto panic_error; /* mode */ + + if (MYread_word (debugsock, &x)) + goto panic_error; /* mask */ + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], c); + MYwrite_word (mumkid[1], x); + for (k = 1, j = 0; k != 0x80000000; k *= 2, j++) + if ((k & x) && passon (debugsock, mumkid[1], 4)) + goto panic_error; + break; + + case RDP_CPread: + /* Read Co-Processor State */ +#ifdef DEBUG + fprintf (stderr, "RDP Read CP state\n"); +#endif + if (MYread_char (debugsock, &CPnum)) + goto panic_error; + + if (MYread_word (debugsock, &mask)) + goto panic_error; + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], CPnum); + MYwrite_word (mumkid[1], mask); + break; + + case RDP_CPwrite: + /* Write Co-Processor State */ +#ifdef DEBUG + fprintf (stderr, "RDP Write CP state\n"); +#endif + if (MYread_char (debugsock, &CPnum)) + goto panic_error; + + if (MYread_word (debugsock, &mask)) + goto panic_error; + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], c); + MYwrite_char (mumkid[1], x); + for (k = 1, j = 0; k != 0x80000000; k *= 2, j++) + if (k & x) + { + if ((c == 1 || c == 2) && k <= 128) + { + /* FP register = 12 bytes + 4 bytes format */ + if (passon (debugsock, mumkid[1], 16)) + goto panic_error; + } + else + { + /* Normal register = 4 bytes */ + if (passon (debugsock, mumkid[1], 4)) + goto panic_error; + } + } + break; + + case RDP_SetBreak: + /* Set Breakpoint */ +#ifdef DEBUG + fprintf (stderr, "RDP Set Breakpoint\n"); +#endif + if (MYread_word (debugsock, &x)) + goto panic_error; /* address */ + + if (MYread_char (debugsock, &c)) + goto panic_error; /* type */ + + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], x); + MYwrite_char (mumkid[1], c); + if (((c & 0xf) >= 5) && passon (debugsock, mumkid[1], 4)) + goto panic_error; /* bound */ + break; + + case RDP_ClearBreak: + /* Clear Breakpoint */ +#ifdef DEBUG + fprintf (stderr, "RDP Clear Breakpoint\n"); +#endif + MYwrite_char (mumkid[1], message); + if (passon (debugsock, mumkid[1], 4)) + goto panic_error; /* point */ + break; + + case RDP_SetWatch: + /* Set Watchpoint */ +#ifdef DEBUG + fprintf (stderr, "RDP Set Watchpoint\n"); +#endif + if (MYread_word (debugsock, &x)) + goto panic_error; /* address */ + + if (MYread_char (debugsock, &c)) + goto panic_error; /* type */ + + if (MYread_char (debugsock, &d)) + goto panic_error; /* datatype */ + + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], x); + MYwrite_char (mumkid[1], c); + MYwrite_char (mumkid[1], d); + if (((c & 0xf) >= 5) && passon (debugsock, mumkid[1], 4)) + goto panic_error; /* bound */ + break; + + case RDP_ClearWatch: + /* Clear Watchpoint */ +#ifdef DEBUG + fprintf (stderr, "RDP Clear Watchpoint\n"); +#endif + MYwrite_char (mumkid[1], message); + if (passon (debugsock, mumkid[1], 4)) + goto panic_error; /* point */ + break; + + case RDP_Execute: + /* Excecute */ +#ifdef DEBUG + fprintf (stderr, "RDP Execute\n"); +#endif + + /* LEAVE THIS ONE 'TIL LATER... */ + /* NEED TO WORK THINGS OUT */ + + /* NO ASCYNCHROUS RUNNING */ + + if (MYread_char (debugsock, &c)) + goto panic_error; /* return */ + + /* Remember incase bit 7 is set and we have to send back a word */ + exreturn = c; + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], c); + break; + + case RDP_Step: + /* Step */ +#ifdef DEBUG + fprintf (stderr, "RDP Step\n"); +#endif + + if (MYread_char (debugsock, &c)) + goto panic_error; /* return */ + + if (MYread_word (debugsock, &x)) + goto panic_error; /* ninstr */ + + MYwrite_char (mumkid[1], message); + MYwrite_char (mumkid[1], c); + MYwrite_word (mumkid[1], x); + break; + + case RDP_Info: + /* Info */ +#ifdef DEBUG + fprintf (stderr, "RDP Info\n"); +#endif + /* INFO TARGET, SET RDI LEVEL */ + if (MYread_word (debugsock, &messagetype)) + goto panic_error; /* info */ + + switch (messagetype) + { + case RDIInfo_Target: + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], messagetype); + break; + + case RDISet_RDILevel: + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], messagetype); + if (passon (debugsock, mumkid[1], 1)) + goto panic_error; /* argument */ + break; + + case RDISet_Cmdline: + /* Got to pass on a string argument */ + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], messagetype); + do + { + if (MYread_char (debugsock, &c)) + goto panic_error; + + MYwrite_char (mumkid[1], c); + } + while (c); + break; + + case RDISignal_Stop: + kill (child, SIGUSR1); + MYwrite_char (debugsock, RDP_Return); + MYwrite_char (debugsock, RDIError_UserInterrupt); + break; + + case RDIVector_Catch: + MYread_word (debugsock, &x); + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], messagetype); + MYwrite_word (mumkid[1], x); + break; + + case RDIInfo_Step: + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], messagetype); + break; + + case RDIInfo_Points: + MYwrite_char (mumkid[1], message); + MYwrite_word (mumkid[1], messagetype); + break; + + default: + fprintf (stderr, "Unrecognized RDIInfo request %d\n", + messagetype); + goto panic_error; + } + break; + + case RDP_OSOpReply: + /* OS Operation Reply */ +#ifdef DEBUG + fprintf (stderr, "RDP OS Reply\n"); +#endif + MYwrite_char (mumkid[1], message); + if (MYread_char (debugsock, &message)) + goto panic_error; + MYwrite_char (mumkid[1], message); + switch (message) + { + case 0: /* return value i.e. nothing else. */ + break; + + case 1: /* returns a byte... */ + if (MYread_char (debugsock, &c)) + goto panic_error; + + MYwrite_char (mumkid[1], c); + break; + + case 2: /* returns a word... */ + if (MYread_word (debugsock, &x)) + goto panic_error; + + MYwrite_word (mumkid[1], x); + break; + } + break; + + case RDP_Reset: + /* Reset */ +#ifdef DEBUG + fprintf (stderr, "RDP Reset\n"); +#endif + MYwrite_char (mumkid[1], message); + break; + + default: + /* Hmm.. bad RDP operation */ + fprintf (stderr, "RDP Bad RDP request (%d)\n", message); + MYwrite_char (debugsock, RDP_Return); + MYwrite_char (debugsock, RDIError_UnimplementedMessage); + break; + } + } + + if (FD_ISSET (kidmum[0], &readfds)) + { +#ifdef DEBUG + fprintf (stderr, "->ARMulator\n"); +#endif + /* Anything we get from the ARMulator has to go to the debugger... */ + /* It is that simple! */ + + passon (kidmum[0], debugsock, 1); + } + } +}
parent.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: bag.c =================================================================== --- bag.c (nonexistent) +++ bag.c (revision 816) @@ -0,0 +1,166 @@ +/* bag.c -- ARMulator support code: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/********************************************************************/ +/* bag.c: */ +/* Offers a data structure for storing and getting pairs of number. */ +/* The numbers are stored together, put one can be looked up by */ +/* quoting the other. If a new pair is entered and one of the */ +/* numbers is a repeat of a previous pair, then the previos pair */ +/* is deleted. */ +/********************************************************************/ + +#include "bag.h" +#include + +#define HASH_TABLE_SIZE 256 +#define hash(x) (((x)&0xff)^(((x)>>8)&0xff)^(((x)>>16)&0xff)^(((x)>>24)&0xff)) + +typedef struct hashentry +{ + struct hashentry *next; + int first; + int second; +} +Hashentry; + +Hashentry *lookupbyfirst[HASH_TABLE_SIZE]; +Hashentry *lookupbysecond[HASH_TABLE_SIZE]; + +void +addtolist (Hashentry ** add, long first, long second) +{ + while (*add) + add = &((*add)->next); + /* Malloc will never fail? :o( */ + (*add) = (Hashentry *) malloc (sizeof (Hashentry)); + (*add)->next = (Hashentry *) 0; + (*add)->first = first; + (*add)->second = second; +} + +void +killwholelist (Hashentry * p) +{ + Hashentry *q; + + while (p) + { + q = p; + p = p->next; + free (q); + } +} + +static void +removefromlist (Hashentry ** p, long first) +{ + Hashentry *q; + + while (*p) + { + if ((*p)->first == first) + { + q = (*p)->next; + free (*p); + *p = q; + return; + } + p = &((*p)->next); + } +} + +void +BAG_putpair (long first, long second) +{ + long junk; + + if (BAG_getfirst (&junk, second) != NO_SUCH_PAIR) + BAG_killpair_bysecond (second); + addtolist (&lookupbyfirst[hash (first)], first, second); + addtolist (&lookupbysecond[hash (second)], first, second); +} + +Bag_error +BAG_getfirst (long *first, long second) +{ + Hashentry *look; + + look = lookupbysecond[hash (second)]; + while (look) + if (look->second == second) + { + *first = look->first; + return NO_ERROR; + } + return NO_SUCH_PAIR; +} + +Bag_error +BAG_getsecond (long first, long *second) +{ + Hashentry *look; + + look = lookupbyfirst[hash (first)]; + while (look) + { + if (look->first == first) + { + *second = look->second; + return NO_ERROR; + } + look = look->next; + } + return NO_SUCH_PAIR; +} + +Bag_error +BAG_killpair_byfirst (long first) +{ + long second; + + if (BAG_getsecond (first, &second) == NO_SUCH_PAIR) + return NO_SUCH_PAIR; + removefromlist (&lookupbyfirst[hash (first)], first); + removefromlist (&lookupbysecond[hash (second)], first); + return NO_ERROR; +} + +Bag_error +BAG_killpair_bysecond (long second) +{ + long first; + + if (BAG_getfirst (&first, second) == NO_SUCH_PAIR) + return NO_SUCH_PAIR; + removefromlist (&lookupbyfirst[hash (first)], first); + removefromlist (&lookupbysecond[hash (second)], first); + return NO_ERROR; +} + +void +BAG_newbag () +{ + int i; + + for (i = 0; i < 256; i++) + { + killwholelist (lookupbyfirst[i]); + killwholelist (lookupbysecond[i]); + lookupbyfirst[i] = lookupbysecond[i] = (Hashentry *) 0; + } +}
bag.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: config.in =================================================================== --- config.in (nonexistent) +++ config.in (revision 816) @@ -0,0 +1,104 @@ +/* config.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FPU_CONTROL_H + +/* Define to 1 if you have the `getrusage' function. */ +#undef HAVE_GETRUSAGE + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the 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. */ +#undef HAVE_SYS_RESOURCE_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_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the `time' function. */ +#undef HAVE_TIME + +/* Define to 1 if you have the header file. */ +#undef HAVE_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ZLIB_H + +/* Define to 1 if you have the `__setfpucw' function. */ +#undef HAVE___SETFPUCW + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Additional package description */ +#undef PKGVERSION + +/* Bug reporting address */ +#undef REPORT_BUGS_TO + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS Index: gdbhost.c =================================================================== --- gdbhost.c (nonexistent) +++ gdbhost.c (revision 816) @@ -0,0 +1,113 @@ +/* gdbhost.c -- ARMulator RDP to gdb comms code: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/***********************************************************/ +/* Functions that communicate info back to the debugger... */ +/***********************************************************/ + +#include +#include +#include "armdefs.h" +#include "communicate.h" +#include "dbg_rdi.h" +#include "armos.h" + +#define OS_SendNothing 0x0 +#define OS_SendChar 0x1 +#define OS_SendWord 0x2 +#define OS_SendString 0x3 + +/* Defined in kid.c */ +extern int wait_for_osreply (ARMword * reply); + +/* A pipe for handling SWI return values that goes straight from the */ +/* parent to the ARMulator host interface, bypassing the childs RDP */ +/* to RDI interpreter */ +int DebuggerARMul[2]; + +/* The pipes between the two processes */ +int mumkid[2]; +int kidmum[2]; + +void +myprint (void *arg, const char *format, va_list ap) +{ +#ifdef DEBUG + fprintf (stderr, "Host: myprint\n"); +#endif + vfprintf (stderr, format, ap); +} + + +/* Waits for a keypress on the debuggers' keyboard */ +void +mypause (void *arg) +{ +#ifdef DEBUG + fprintf (stderr, "Host: mypause\n"); +#endif +} /* I do love exciting functions */ + +void +mywritec (void *arg, int c) +{ +#ifdef DEBUG + fprintf (stderr, "Mywrite : %c\n", c); +#endif + MYwrite_char (kidmum[1], RDP_OSOp); /* OS Operation Request Message */ + MYwrite_word (kidmum[1], SWI_WriteC); /* Print... */ + MYwrite_char (kidmum[1], OS_SendChar); /* ...a single character */ + MYwrite_char (kidmum[1], (unsigned char) c); + + wait_for_osreply ((ARMword *) 0); +} + +int +myreadc (void *arg) +{ + char c; + ARMword x; + +#ifdef DEBUG + fprintf (stderr, "Host: myreadc\n"); +#endif + MYwrite_char (kidmum[1], RDP_OSOp); /* OS Operation Request Message */ + MYwrite_word (kidmum[1], SWI_ReadC); /* Read... */ + MYwrite_char (kidmum[1], OS_SendNothing); + + c = wait_for_osreply (&x); + return (x); +} + + +int +mywrite (void *arg, char const *buffer, int len) +{ +#ifdef DEBUG + fprintf (stderr, "Host: mywrite\n"); +#endif + return 0; +} + +char * +mygets (void *arg, char *buffer, int len) +{ +#ifdef DEBUG + fprintf (stderr, "Host: mygets\n"); +#endif + return buffer; +}
gdbhost.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: bag.h =================================================================== --- bag.h (nonexistent) +++ bag.h (revision 816) @@ -0,0 +1,43 @@ +/* bag.h -- ARMulator support code: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/********************************************************************/ +/* bag.h: */ +/* Header file for bag.c */ +/* Offers a data structure for storing and getting pairs of number. */ +/* The numbers are stored together, put one can be looked up by */ +/* quoting the other. If a new pair is entered and one of the */ +/* numbers is a repeat of a previous pair, then the previos pair */ +/* is deleted. */ +/********************************************************************/ + +typedef enum +{ + NO_ERROR, + DELETED_OLD_PAIR, + NO_SUCH_PAIR, +} +Bag_error; + +void BAG_putpair (long first, long second); + +void BAG_newbag (void); +Bag_error BAG_killpair_byfirst (long first); +Bag_error BAG_killpair_bysecond (long second); + +Bag_error BAG_getfirst (long *first, long second); +Bag_error BAG_getsecond (long first, long *second);
bag.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: gdbhost.h =================================================================== --- gdbhost.h (nonexistent) +++ gdbhost.h (revision 816) @@ -0,0 +1,23 @@ +/* gdbhost.h -- ARMulator to gdb interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +void myprint (void *arg, const char *format, va_list ap); +void mypause (void *arg); +void mywritec (void *arg, int c); +int myreadc (void *arg); +int mywrite (void *arg, char const *buffer, int len); +char *mygets (void *arg, char *buffer, int len);
gdbhost.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: maverick.c =================================================================== --- maverick.c (nonexistent) +++ maverick.c (revision 816) @@ -0,0 +1,1290 @@ +/* maverick.c -- Cirrus/DSP co-processor interface. + Copyright (C) 2003, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + Contributed by Aldy Hernandez (aldyh@redhat.com). + + 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 "armdefs.h" +#include "ansidecl.h" +#include "armemu.h" + +/*#define CIRRUS_DEBUG 1 /**/ +#if CIRRUS_DEBUG +# define printfdbg printf +#else +# define printfdbg printf_nothing +#endif + +#define POS64(i) ( (~(i)) >> 63 ) +#define NEG64(i) ( (i) >> 63 ) + +/* Define Co-Processor instruction handlers here. */ + +/* Here's ARMulator's DSP definition. A few things to note: + 1) it has 16 64-bit registers and 4 72-bit accumulators + 2) you can only access its registers with MCR and MRC. */ + +/* We can't define these in here because this file might not be linked + unless the target is arm9e-*. They are defined in wrapper.c. + Eventually the simulator should be made to handle any coprocessor + at run time. */ +struct maverick_regs +{ + union + { + int i; + float f; + } upper; + + union + { + int i; + float f; + } lower; +}; + +union maverick_acc_regs +{ + long double ld; /* Acc registers are 72-bits. */ +}; + +struct maverick_regs DSPregs[16]; +union maverick_acc_regs DSPacc[4]; +ARMword DSPsc; + +#define DEST_REG (BITS (12, 15)) +#define SRC1_REG (BITS (16, 19)) +#define SRC2_REG (BITS (0, 3)) + +static int lsw_int_index, msw_int_index; +static int lsw_float_index, msw_float_index; + +static double mv_getRegDouble (int); +static long long mv_getReg64int (int); +static void mv_setRegDouble (int, double val); +static void mv_setReg64int (int, long long val); + +static union +{ + double d; + long long ll; + int ints[2]; +} reg_conv; + +static void +printf_nothing (void * foo, ...) +{ +} + +static void +cirrus_not_implemented (char * insn) +{ + fprintf (stderr, "Cirrus instruction '%s' not implemented.\n", insn); + fprintf (stderr, "aborting!\n"); + + exit (1); +} + +static unsigned +DSPInit (ARMul_State * state) +{ + ARMul_ConsolePrint (state, ", DSP present"); + return TRUE; +} + +unsigned +DSPMRC4 (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword * value) +{ + switch (BITS (5, 7)) + { + case 0: /* cfmvrdl */ + /* Move lower half of a DF stored in a DSP reg into an Arm reg. */ + printfdbg ("cfmvrdl\n"); + printfdbg ("\tlower half=0x%x\n", DSPregs[SRC1_REG].lower.i); + printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG)); + + *value = (ARMword) DSPregs[SRC1_REG].lower.i; + break; + + case 1: /* cfmvrdh */ + /* Move upper half of a DF stored in a DSP reg into an Arm reg. */ + printfdbg ("cfmvrdh\n"); + printfdbg ("\tupper half=0x%x\n", DSPregs[SRC1_REG].upper.i); + printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG)); + + *value = (ARMword) DSPregs[SRC1_REG].upper.i; + break; + + case 2: /* cfmvrs */ + /* Move SF from upper half of a DSP register to an Arm register. */ + *value = (ARMword) DSPregs[SRC1_REG].upper.i; + printfdbg ("cfmvrs = mvf%d <-- %f\n", + SRC1_REG, + DSPregs[SRC1_REG].upper.f); + break; + +#ifdef doesnt_work + case 4: /* cfcmps */ + { + float a, b; + int n, z, c, v; + + a = DSPregs[SRC1_REG].upper.f; + b = DSPregs[SRC2_REG].upper.f; + + printfdbg ("cfcmps\n"); + printfdbg ("\tcomparing %f and %f\n", a, b); + + z = a == b; /* zero */ + n = a != b; /* negative */ + v = a > b; /* overflow */ + c = 0; /* carry */ + *value = (n << 31) | (z << 30) | (c << 29) | (v << 28); + break; + } + + case 5: /* cfcmpd */ + { + double a, b; + int n, z, c, v; + + a = mv_getRegDouble (SRC1_REG); + b = mv_getRegDouble (SRC2_REG); + + printfdbg ("cfcmpd\n"); + printfdbg ("\tcomparing %g and %g\n", a, b); + + z = a == b; /* zero */ + n = a != b; /* negative */ + v = a > b; /* overflow */ + c = 0; /* carry */ + *value = (n << 31) | (z << 30) | (c << 29) | (v << 28); + break; + } +#else + case 4: /* cfcmps */ + { + float a, b; + int n, z, c, v; + + a = DSPregs[SRC1_REG].upper.f; + b = DSPregs[SRC2_REG].upper.f; + + printfdbg ("cfcmps\n"); + printfdbg ("\tcomparing %f and %f\n", a, b); + + z = a == b; /* zero */ + n = a < b; /* negative */ + c = a > b; /* carry */ + v = 0; /* fixme */ + printfdbg ("\tz = %d, n = %d\n", z, n); + *value = (n << 31) | (z << 30) | (c << 29) | (v << 28); + break; + } + + case 5: /* cfcmpd */ + { + double a, b; + int n, z, c, v; + + a = mv_getRegDouble (SRC1_REG); + b = mv_getRegDouble (SRC2_REG); + + printfdbg ("cfcmpd\n"); + printfdbg ("\tcomparing %g and %g\n", a, b); + + z = a == b; /* zero */ + n = a < b; /* negative */ + c = a > b; /* carry */ + v = 0; /* fixme */ + *value = (n << 31) | (z << 30) | (c << 29) | (v << 28); + break; + } +#endif + default: + fprintf (stderr, "unknown opcode in DSPMRC4 0x%x\n", instr); + cirrus_not_implemented ("unknown"); + break; + } + + return ARMul_DONE; +} + +unsigned +DSPMRC5 (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword * value) +{ + switch (BITS (5, 7)) + { + case 0: /* cfmvr64l */ + /* Move lower half of 64bit int from Cirrus to Arm. */ + *value = (ARMword) DSPregs[SRC1_REG].lower.i; + printfdbg ("cfmvr64l ARM_REG = mvfx%d <-- %d\n", + DEST_REG, + (int) *value); + break; + + case 1: /* cfmvr64h */ + /* Move upper half of 64bit int from Cirrus to Arm. */ + *value = (ARMword) DSPregs[SRC1_REG].upper.i; + printfdbg ("cfmvr64h <-- %d\n", (int) *value); + break; + + case 4: /* cfcmp32 */ + { + int res; + int n, z, c, v; + unsigned int a, b; + + printfdbg ("cfcmp32 mvfx%d - mvfx%d\n", + SRC1_REG, + SRC2_REG); + + /* FIXME: see comment for cfcmps. */ + a = DSPregs[SRC1_REG].lower.i; + b = DSPregs[SRC2_REG].lower.i; + + res = DSPregs[SRC1_REG].lower.i - DSPregs[SRC2_REG].lower.i; + /* zero */ + z = res == 0; + /* negative */ + n = res < 0; + /* overflow */ + v = SubOverflow (DSPregs[SRC1_REG].lower.i, DSPregs[SRC2_REG].lower.i, + res); + /* carry */ + c = (NEG (a) && POS (b) || + (NEG (a) && POS (res)) || (POS (b) && POS (res))); + + *value = (n << 31) | (z << 30) | (c << 29) | (v << 28); + break; + } + + case 5: /* cfcmp64 */ + { + long long res; + int n, z, c, v; + unsigned long long a, b; + + printfdbg ("cfcmp64 mvdx%d - mvdx%d\n", + SRC1_REG, + SRC2_REG); + + /* fixme: see comment for cfcmps. */ + + a = mv_getReg64int (SRC1_REG); + b = mv_getReg64int (SRC2_REG); + + res = mv_getReg64int (SRC1_REG) - mv_getReg64int (SRC2_REG); + /* zero */ + z = res == 0; + /* negative */ + n = res < 0; + /* overflow */ + v = ((NEG64 (a) && POS64 (b) && POS64 (res)) + || (POS64 (a) && NEG64 (b) && NEG64 (res))); + /* carry */ + c = (NEG64 (a) && POS64 (b) || + (NEG64 (a) && POS64 (res)) || (POS64 (b) && POS64 (res))); + + *value = (n << 31) | (z << 30) | (c << 29) | (v << 28); + break; + } + + default: + fprintf (stderr, "unknown opcode in DSPMRC5 0x%x\n", instr); + cirrus_not_implemented ("unknown"); + break; + } + + return ARMul_DONE; +} + +unsigned +DSPMRC6 (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword * value) +{ + switch (BITS (5, 7)) + { + case 0: /* cfmval32 */ + cirrus_not_implemented ("cfmval32"); + break; + + case 1: /* cfmvam32 */ + cirrus_not_implemented ("cfmvam32"); + break; + + case 2: /* cfmvah32 */ + cirrus_not_implemented ("cfmvah32"); + break; + + case 3: /* cfmva32 */ + cirrus_not_implemented ("cfmva32"); + break; + + case 4: /* cfmva64 */ + cirrus_not_implemented ("cfmva64"); + break; + + case 5: /* cfmvsc32 */ + cirrus_not_implemented ("cfmvsc32"); + break; + + default: + fprintf (stderr, "unknown opcode in DSPMRC6 0x%x\n", instr); + cirrus_not_implemented ("unknown"); + break; + } + + return ARMul_DONE; +} + +unsigned +DSPMCR4 (ARMul_State * state, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword value) +{ + switch (BITS (5, 7)) + { + case 0: /* cfmvdlr */ + /* Move the lower half of a DF value from an Arm register into + the lower half of a Cirrus register. */ + printfdbg ("cfmvdlr <-- 0x%x\n", (int) value); + DSPregs[SRC1_REG].lower.i = (int) value; + break; + + case 1: /* cfmvdhr */ + /* Move the upper half of a DF value from an Arm register into + the upper half of a Cirrus register. */ + printfdbg ("cfmvdhr <-- 0x%x\n", (int) value); + DSPregs[SRC1_REG].upper.i = (int) value; + break; + + case 2: /* cfmvsr */ + /* Move SF from Arm register into upper half of Cirrus register. */ + printfdbg ("cfmvsr <-- 0x%x\n", (int) value); + DSPregs[SRC1_REG].upper.i = (int) value; + break; + + default: + fprintf (stderr, "unknown opcode in DSPMCR4 0x%x\n", instr); + cirrus_not_implemented ("unknown"); + break; + } + + return ARMul_DONE; +} + +unsigned +DSPMCR5 (ARMul_State * state, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword value) +{ + union + { + int s; + unsigned int us; + } val; + + switch (BITS (5, 7)) + { + case 0: /* cfmv64lr */ + /* Move lower half of a 64bit int from an ARM register into the + lower half of a DSP register and sign extend it. */ + printfdbg ("cfmv64lr mvdx%d <-- 0x%x\n", SRC1_REG, (int) value); + DSPregs[SRC1_REG].lower.i = (int) value; + break; + + case 1: /* cfmv64hr */ + /* Move upper half of a 64bit int from an ARM register into the + upper half of a DSP register. */ + printfdbg ("cfmv64hr ARM_REG = mvfx%d <-- 0x%x\n", + SRC1_REG, + (int) value); + DSPregs[SRC1_REG].upper.i = (int) value; + break; + + case 2: /* cfrshl32 */ + printfdbg ("cfrshl32\n"); + val.us = value; + if (val.s > 0) + DSPregs[SRC2_REG].lower.i = DSPregs[SRC1_REG].lower.i << value; + else + DSPregs[SRC2_REG].lower.i = DSPregs[SRC1_REG].lower.i >> -value; + break; + + case 3: /* cfrshl64 */ + printfdbg ("cfrshl64\n"); + val.us = value; + if (val.s > 0) + mv_setReg64int (SRC2_REG, mv_getReg64int (SRC1_REG) << value); + else + mv_setReg64int (SRC2_REG, mv_getReg64int (SRC1_REG) >> -value); + break; + + default: + fprintf (stderr, "unknown opcode in DSPMCR5 0x%x\n", instr); + cirrus_not_implemented ("unknown"); + break; + } + + return ARMul_DONE; +} + +unsigned +DSPMCR6 (ARMul_State * state, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword value) +{ + switch (BITS (5, 7)) + { + case 0: /* cfmv32al */ + cirrus_not_implemented ("cfmv32al"); + break; + + case 1: /* cfmv32am */ + cirrus_not_implemented ("cfmv32am"); + break; + + case 2: /* cfmv32ah */ + cirrus_not_implemented ("cfmv32ah"); + break; + + case 3: /* cfmv32a */ + cirrus_not_implemented ("cfmv32a"); + break; + + case 4: /* cfmv64a */ + cirrus_not_implemented ("cfmv64a"); + break; + + case 5: /* cfmv32sc */ + cirrus_not_implemented ("cfmv32sc"); + break; + + default: + fprintf (stderr, "unknown opcode in DSPMCR6 0x%x\n", instr); + cirrus_not_implemented ("unknown"); + break; + } + + return ARMul_DONE; +} + +unsigned +DSPLDC4 (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type, + ARMword instr, + ARMword data) +{ + static unsigned words; + + if (type != ARMul_DATA) + { + words = 0; + return ARMul_DONE; + } + + if (BIT (22)) + { /* it's a long access, get two words */ + /* cfldrd */ + + printfdbg ("cfldrd: %x (words = %d) (bigend = %d) DESTREG = %d\n", + data, words, state->bigendSig, DEST_REG); + + if (words == 0) + { + if (state->bigendSig) + DSPregs[DEST_REG].upper.i = (int) data; + else + DSPregs[DEST_REG].lower.i = (int) data; + } + else + { + if (state->bigendSig) + DSPregs[DEST_REG].lower.i = (int) data; + else + DSPregs[DEST_REG].upper.i = (int) data; + } + + ++ words; + + if (words == 2) + { + printfdbg ("\tmvd%d <-- mem = %g\n", DEST_REG, + mv_getRegDouble (DEST_REG)); + + return ARMul_DONE; + } + else + return ARMul_INC; + } + else + { + /* Get just one word. */ + + /* cfldrs */ + printfdbg ("cfldrs\n"); + + DSPregs[DEST_REG].upper.i = (int) data; + + printfdbg ("\tmvf%d <-- mem = %f\n", DEST_REG, + DSPregs[DEST_REG].upper.f); + + return ARMul_DONE; + } +} + +unsigned +DSPLDC5 (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type, + ARMword instr, + ARMword data) +{ + static unsigned words; + + if (type != ARMul_DATA) + { + words = 0; + return ARMul_DONE; + } + + if (BIT (22)) + { + /* It's a long access, get two words. */ + + /* cfldr64 */ + printfdbg ("cfldr64: %d\n", data); + + if (words == 0) + { + if (state->bigendSig) + DSPregs[DEST_REG].upper.i = (int) data; + else + DSPregs[DEST_REG].lower.i = (int) data; + } + else + { + if (state->bigendSig) + DSPregs[DEST_REG].lower.i = (int) data; + else + DSPregs[DEST_REG].upper.i = (int) data; + } + + ++ words; + + if (words == 2) + { + printfdbg ("\tmvdx%d <-- mem = %lld\n", DEST_REG, + mv_getReg64int (DEST_REG)); + + return ARMul_DONE; + } + else + return ARMul_INC; + } + else + { + /* Get just one word. */ + + /* cfldr32 */ + printfdbg ("cfldr32 mvfx%d <-- %d\n", DEST_REG, (int) data); + + /* 32bit ints should be sign extended to 64bits when loaded. */ + mv_setReg64int (DEST_REG, (long long) data); + + return ARMul_DONE; + } +} + +unsigned +DSPSTC4 (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type, + ARMword instr, + ARMword * data) +{ + static unsigned words; + + if (type != ARMul_DATA) + { + words = 0; + return ARMul_DONE; + } + + if (BIT (22)) + { + /* It's a long access, get two words. */ + /* cfstrd */ + printfdbg ("cfstrd\n"); + + if (words == 0) + { + if (state->bigendSig) + *data = (ARMword) DSPregs[DEST_REG].upper.i; + else + *data = (ARMword) DSPregs[DEST_REG].lower.i; + } + else + { + if (state->bigendSig) + *data = (ARMword) DSPregs[DEST_REG].lower.i; + else + *data = (ARMword) DSPregs[DEST_REG].upper.i; + } + + ++ words; + + if (words == 2) + { + printfdbg ("\tmem = mvd%d = %g\n", DEST_REG, + mv_getRegDouble (DEST_REG)); + + return ARMul_DONE; + } + else + return ARMul_INC; + } + else + { + /* Get just one word. */ + /* cfstrs */ + printfdbg ("cfstrs mvf%d <-- %f\n", DEST_REG, + DSPregs[DEST_REG].upper.f); + + *data = (ARMword) DSPregs[DEST_REG].upper.i; + + return ARMul_DONE; + } +} + +unsigned +DSPSTC5 (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type, + ARMword instr, + ARMword * data) +{ + static unsigned words; + + if (type != ARMul_DATA) + { + words = 0; + return ARMul_DONE; + } + + if (BIT (22)) + { + /* It's a long access, store two words. */ + /* cfstr64 */ + printfdbg ("cfstr64\n"); + + if (words == 0) + { + if (state->bigendSig) + *data = (ARMword) DSPregs[DEST_REG].upper.i; + else + *data = (ARMword) DSPregs[DEST_REG].lower.i; + } + else + { + if (state->bigendSig) + *data = (ARMword) DSPregs[DEST_REG].lower.i; + else + *data = (ARMword) DSPregs[DEST_REG].upper.i; + } + + ++ words; + + if (words == 2) + { + printfdbg ("\tmem = mvd%d = %lld\n", DEST_REG, + mv_getReg64int (DEST_REG)); + + return ARMul_DONE; + } + else + return ARMul_INC; + } + else + { + /* Store just one word. */ + /* cfstr32 */ + *data = (ARMword) DSPregs[DEST_REG].lower.i; + + printfdbg ("cfstr32 MEM = %d\n", (int) *data); + + return ARMul_DONE; + } +} + +unsigned +DSPCDP4 (ARMul_State * state, + unsigned type, + ARMword instr) +{ + int opcode2; + + opcode2 = BITS (5,7); + + switch (BITS (20,21)) + { + case 0: + switch (opcode2) + { + case 0: /* cfcpys */ + printfdbg ("cfcpys mvf%d = mvf%d = %f\n", + DEST_REG, + SRC1_REG, + DSPregs[SRC1_REG].upper.f); + DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f; + break; + + case 1: /* cfcpyd */ + printfdbg ("cfcpyd mvd%d = mvd%d = %g\n", + DEST_REG, + SRC1_REG, + mv_getRegDouble (SRC1_REG)); + mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG)); + break; + + case 2: /* cfcvtds */ + printfdbg ("cfcvtds mvf%d = (float) mvd%d = %f\n", + DEST_REG, + SRC1_REG, + (float) mv_getRegDouble (SRC1_REG)); + DSPregs[DEST_REG].upper.f = (float) mv_getRegDouble (SRC1_REG); + break; + + case 3: /* cfcvtsd */ + printfdbg ("cfcvtsd mvd%d = mvf%d = %g\n", + DEST_REG, + SRC1_REG, + (double) DSPregs[SRC1_REG].upper.f); + mv_setRegDouble (DEST_REG, (double) DSPregs[SRC1_REG].upper.f); + break; + + case 4: /* cfcvt32s */ + printfdbg ("cfcvt32s mvf%d = mvfx%d = %f\n", + DEST_REG, + SRC1_REG, + (float) DSPregs[SRC1_REG].lower.i); + DSPregs[DEST_REG].upper.f = (float) DSPregs[SRC1_REG].lower.i; + break; + + case 5: /* cfcvt32d */ + printfdbg ("cfcvt32d mvd%d = mvfx%d = %g\n", + DEST_REG, + SRC1_REG, + (double) DSPregs[SRC1_REG].lower.i); + mv_setRegDouble (DEST_REG, (double) DSPregs[SRC1_REG].lower.i); + break; + + case 6: /* cfcvt64s */ + printfdbg ("cfcvt64s mvf%d = mvdx%d = %f\n", + DEST_REG, + SRC1_REG, + (float) mv_getReg64int (SRC1_REG)); + DSPregs[DEST_REG].upper.f = (float) mv_getReg64int (SRC1_REG); + break; + + case 7: /* cfcvt64d */ + printfdbg ("cfcvt64d mvd%d = mvdx%d = %g\n", + DEST_REG, + SRC1_REG, + (double) mv_getReg64int (SRC1_REG)); + mv_setRegDouble (DEST_REG, (double) mv_getReg64int (SRC1_REG)); + break; + } + break; + + case 1: + switch (opcode2) + { + case 0: /* cfmuls */ + printfdbg ("cfmuls mvf%d = mvf%d = %f\n", + DEST_REG, + SRC1_REG, + DSPregs[SRC1_REG].upper.f * DSPregs[SRC2_REG].upper.f); + + DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f + * DSPregs[SRC2_REG].upper.f; + break; + + case 1: /* cfmuld */ + printfdbg ("cfmuld mvd%d = mvd%d = %g\n", + DEST_REG, + SRC1_REG, + mv_getRegDouble (SRC1_REG) * mv_getRegDouble (SRC2_REG)); + + mv_setRegDouble (DEST_REG, + mv_getRegDouble (SRC1_REG) + * mv_getRegDouble (SRC2_REG)); + break; + + default: + fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr); + cirrus_not_implemented ("unknown"); + break; + } + break; + + case 3: + switch (opcode2) + { + case 0: /* cfabss */ + DSPregs[DEST_REG].upper.f = (DSPregs[SRC1_REG].upper.f < 0.0F ? + -DSPregs[SRC1_REG].upper.f + : DSPregs[SRC1_REG].upper.f); + printfdbg ("cfabss mvf%d = |mvf%d| = %f\n", + DEST_REG, + SRC1_REG, + DSPregs[DEST_REG].upper.f); + break; + + case 1: /* cfabsd */ + mv_setRegDouble (DEST_REG, + (mv_getRegDouble (SRC1_REG) < 0.0 ? + -mv_getRegDouble (SRC1_REG) + : mv_getRegDouble (SRC1_REG))); + printfdbg ("cfabsd mvd%d = |mvd%d| = %g\n", + DEST_REG, + SRC1_REG, + mv_getRegDouble (DEST_REG)); + break; + + case 2: /* cfnegs */ + DSPregs[DEST_REG].upper.f = -DSPregs[SRC1_REG].upper.f; + printfdbg ("cfnegs mvf%d = -mvf%d = %f\n", + DEST_REG, + SRC1_REG, + DSPregs[DEST_REG].upper.f); + break; + + case 3: /* cfnegd */ + mv_setRegDouble (DEST_REG, + -mv_getRegDouble (SRC1_REG)); + printfdbg ("cfnegd mvd%d = -mvd%d = %g\n", + DEST_REG, + mv_getRegDouble (DEST_REG)); + break; + + case 4: /* cfadds */ + DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f + + DSPregs[SRC2_REG].upper.f; + printfdbg ("cfadds mvf%d = mvf%d + mvf%d = %f\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + DSPregs[DEST_REG].upper.f); + break; + + case 5: /* cfaddd */ + mv_setRegDouble (DEST_REG, + mv_getRegDouble (SRC1_REG) + + mv_getRegDouble (SRC2_REG)); + printfdbg ("cfaddd: mvd%d = mvd%d + mvd%d = %g\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + mv_getRegDouble (DEST_REG)); + break; + + case 6: /* cfsubs */ + DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f + - DSPregs[SRC2_REG].upper.f; + printfdbg ("cfsubs: mvf%d = mvf%d - mvf%d = %f\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + DSPregs[DEST_REG].upper.f); + break; + + case 7: /* cfsubd */ + mv_setRegDouble (DEST_REG, + mv_getRegDouble (SRC1_REG) + - mv_getRegDouble (SRC2_REG)); + printfdbg ("cfsubd: mvd%d = mvd%d - mvd%d = %g\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + mv_getRegDouble (DEST_REG)); + break; + } + break; + + default: + fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr); + cirrus_not_implemented ("unknown"); + break; + } + + return ARMul_DONE; +} + +unsigned +DSPCDP5 (ARMul_State * state, + unsigned type, + ARMword instr) +{ + int opcode2; + char shift; + + opcode2 = BITS (5,7); + + /* Shift constants are 7bit signed numbers in bits 0..3|5..7. */ + shift = BITS (0, 3) | (BITS (5, 7)) << 4; + if (shift & 0x40) + shift |= 0xc0; + + switch (BITS (20,21)) + { + case 0: + /* cfsh32 */ + printfdbg ("cfsh32 %s amount=%d\n", shift < 0 ? "right" : "left", + shift); + if (shift < 0) + /* Negative shift is a right shift. */ + DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i >> -shift; + else + /* Positive shift is a left shift. */ + DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i << shift; + break; + + case 1: + switch (opcode2) + { + case 0: /* cfmul32 */ + DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i + * DSPregs[SRC2_REG].lower.i; + printfdbg ("cfmul32 mvfx%d = mvfx%d * mvfx%d = %d\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + DSPregs[DEST_REG].lower.i); + break; + + case 1: /* cfmul64 */ + mv_setReg64int (DEST_REG, + mv_getReg64int (SRC1_REG) + * mv_getReg64int (SRC2_REG)); + printfdbg ("cfmul64 mvdx%d = mvdx%d * mvdx%d = %lld\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + mv_getReg64int (DEST_REG)); + break; + + case 2: /* cfmac32 */ + DSPregs[DEST_REG].lower.i + += DSPregs[SRC1_REG].lower.i * DSPregs[SRC2_REG].lower.i; + printfdbg ("cfmac32 mvfx%d += mvfx%d * mvfx%d = %d\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + DSPregs[DEST_REG].lower.i); + break; + + case 3: /* cfmsc32 */ + DSPregs[DEST_REG].lower.i + -= DSPregs[SRC1_REG].lower.i * DSPregs[SRC2_REG].lower.i; + printfdbg ("cfmsc32 mvfx%d -= mvfx%d * mvfx%d = %d\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + DSPregs[DEST_REG].lower.i); + break; + + case 4: /* cfcvts32 */ + /* fixme: this should round */ + DSPregs[DEST_REG].lower.i = (int) DSPregs[SRC1_REG].upper.f; + printfdbg ("cfcvts32 mvfx%d = mvf%d = %d\n", + DEST_REG, + SRC1_REG, + DSPregs[DEST_REG].lower.i); + break; + + case 5: /* cfcvtd32 */ + /* fixme: this should round */ + DSPregs[DEST_REG].lower.i = (int) mv_getRegDouble (SRC1_REG); + printfdbg ("cfcvtd32 mvdx%d = mvd%d = %d\n", + DEST_REG, + SRC1_REG, + DSPregs[DEST_REG].lower.i); + break; + + case 6: /* cftruncs32 */ + DSPregs[DEST_REG].lower.i = (int) DSPregs[SRC1_REG].upper.f; + printfdbg ("cftruncs32 mvfx%d = mvf%d = %d\n", + DEST_REG, + SRC1_REG, + DSPregs[DEST_REG].lower.i); + break; + + case 7: /* cftruncd32 */ + DSPregs[DEST_REG].lower.i = (int) mv_getRegDouble (SRC1_REG); + printfdbg ("cftruncd32 mvfx%d = mvd%d = %d\n", + DEST_REG, + SRC1_REG, + DSPregs[DEST_REG].lower.i); + break; + } + break; + + case 2: + /* cfsh64 */ + printfdbg ("cfsh64\n"); + + if (shift < 0) + /* Negative shift is a right shift. */ + mv_setReg64int (DEST_REG, + mv_getReg64int (SRC1_REG) >> -shift); + else + /* Positive shift is a left shift. */ + mv_setReg64int (DEST_REG, + mv_getReg64int (SRC1_REG) << shift); + printfdbg ("\t%llx\n", mv_getReg64int(DEST_REG)); + break; + + case 3: + switch (opcode2) + { + case 0: /* cfabs32 */ + DSPregs[DEST_REG].lower.i = (DSPregs[SRC1_REG].lower.i < 0 + ? -DSPregs[SRC1_REG].lower.i : DSPregs[SRC1_REG].lower.i); + printfdbg ("cfabs32 mvfx%d = |mvfx%d| = %d\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + DSPregs[DEST_REG].lower.i); + break; + + case 1: /* cfabs64 */ + mv_setReg64int (DEST_REG, + (mv_getReg64int (SRC1_REG) < 0 + ? -mv_getReg64int (SRC1_REG) + : mv_getReg64int (SRC1_REG))); + printfdbg ("cfabs64 mvdx%d = |mvdx%d| = %lld\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + mv_getReg64int (DEST_REG)); + break; + + case 2: /* cfneg32 */ + DSPregs[DEST_REG].lower.i = -DSPregs[SRC1_REG].lower.i; + printfdbg ("cfneg32 mvfx%d = -mvfx%d = %d\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + DSPregs[DEST_REG].lower.i); + break; + + case 3: /* cfneg64 */ + mv_setReg64int (DEST_REG, -mv_getReg64int (SRC1_REG)); + printfdbg ("cfneg64 mvdx%d = -mvdx%d = %lld\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + mv_getReg64int (DEST_REG)); + break; + + case 4: /* cfadd32 */ + DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i + + DSPregs[SRC2_REG].lower.i; + printfdbg ("cfadd32 mvfx%d = mvfx%d + mvfx%d = %d\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + DSPregs[DEST_REG].lower.i); + break; + + case 5: /* cfadd64 */ + mv_setReg64int (DEST_REG, + mv_getReg64int (SRC1_REG) + + mv_getReg64int (SRC2_REG)); + printfdbg ("cfadd64 mvdx%d = mvdx%d + mvdx%d = %lld\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + mv_getReg64int (DEST_REG)); + break; + + case 6: /* cfsub32 */ + DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i + - DSPregs[SRC2_REG].lower.i; + printfdbg ("cfsub32 mvfx%d = mvfx%d - mvfx%d = %d\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + DSPregs[DEST_REG].lower.i); + break; + + case 7: /* cfsub64 */ + mv_setReg64int (DEST_REG, + mv_getReg64int (SRC1_REG) + - mv_getReg64int (SRC2_REG)); + printfdbg ("cfsub64 mvdx%d = mvdx%d - mvdx%d = %d\n", + DEST_REG, + SRC1_REG, + SRC2_REG, + mv_getReg64int (DEST_REG)); + break; + } + break; + + default: + fprintf (stderr, "unknown opcode in DSPCDP5 0x%x\n", instr); + cirrus_not_implemented ("unknown"); + break; + } + + return ARMul_DONE; +} + +unsigned +DSPCDP6 (ARMul_State * state, + unsigned type, + ARMword instr) +{ + int opcode2; + + opcode2 = BITS (5,7); + + switch (BITS (20,21)) + { + case 0: + /* cfmadd32 */ + cirrus_not_implemented ("cfmadd32"); + break; + + case 1: + /* cfmsub32 */ + cirrus_not_implemented ("cfmsub32"); + break; + + case 2: + /* cfmadda32 */ + cirrus_not_implemented ("cfmadda32"); + break; + + case 3: + /* cfmsuba32 */ + cirrus_not_implemented ("cfmsuba32"); + break; + + default: + fprintf (stderr, "unknown opcode in DSPCDP6 0x%x\n", instr); + } + + return ARMul_DONE; +} + +/* Conversion functions. + + 32-bit integers are stored in the LOWER half of a 64-bit physical + register. + + Single precision floats are stored in the UPPER half of a 64-bit + physical register. */ + +static double +mv_getRegDouble (int regnum) +{ + reg_conv.ints[lsw_float_index] = DSPregs[regnum].upper.i; + reg_conv.ints[msw_float_index] = DSPregs[regnum].lower.i; + return reg_conv.d; +} + +static void +mv_setRegDouble (int regnum, double val) +{ + reg_conv.d = val; + DSPregs[regnum].upper.i = reg_conv.ints[lsw_float_index]; + DSPregs[regnum].lower.i = reg_conv.ints[msw_float_index]; +} + +static long long +mv_getReg64int (int regnum) +{ + reg_conv.ints[lsw_int_index] = DSPregs[regnum].lower.i; + reg_conv.ints[msw_int_index] = DSPregs[regnum].upper.i; + return reg_conv.ll; +} + +static void +mv_setReg64int (int regnum, long long val) +{ + reg_conv.ll = val; + DSPregs[regnum].lower.i = reg_conv.ints[lsw_int_index]; + DSPregs[regnum].upper.i = reg_conv.ints[msw_int_index]; +} + +/* Compute LSW in a double and a long long. */ + +void +mv_compute_host_endianness (ARMul_State * state) +{ + static union + { + long long ll; + long ints[2]; + long i; + double d; + float floats[2]; + float f; + } conv; + + /* Calculate where's the LSW in a 64bit int. */ + conv.ll = 45; + + if (conv.ints[0] == 0) + { + msw_int_index = 0; + lsw_int_index = 1; + } + else + { + assert (conv.ints[1] == 0); + msw_int_index = 1; + lsw_int_index = 0; + } + + /* Calculate where's the LSW in a double. */ + conv.d = 3.0; + + if (conv.ints[0] == 0) + { + msw_float_index = 0; + lsw_float_index = 1; + } + else + { + assert (conv.ints[1] == 0); + msw_float_index = 1; + lsw_float_index = 0; + } + + printfdbg ("lsw_int_index %d\n", lsw_int_index); + printfdbg ("lsw_float_index %d\n", lsw_float_index); +}
maverick.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: ChangeLog =================================================================== --- ChangeLog (nonexistent) +++ ChangeLog (revision 816) @@ -0,0 +1,1243 @@ +2010-01-09 Ralf Wildenhues + + * configure: Regenerate. + +2009-08-22 Ralf Wildenhues + + * config.in: Regenerate. + * configure: Likewise. + + * configure: Regenerate. + +2008-11-24 Joel Sherrill + + * arminit.c, iwmmxt.c: Include to + eliminate warning. +2008-07-11 Hans-Peter Nilsson + + * configure: Regenerate to track ../common/common.m4 changes. + * config.in: Ditto. + +2008-06-06 Vladimir Prus + Daniel Jacobowitz + Joseph Myers + + * configure: Regenerate. + * wrapper.c (sim_target_display_usage): Add help parameter. + +2007-02-27 Mark Mitchell + + * armos.c (SWIflen): Do not treate file descriptor zero as + special. + +2007-02-15 Nick Clifton + + * armemu.c (handle_v6_insn): Fix typo in sign extension test of + the sext and sxtah instructions. + +2007-02-08 Daniel Jacobowitz + + Reported by timeless@gmail.com: + * wrapper.c (sim_target_parse_arg_array): Do not return void value. + +2006-12-21 Hans-Peter Nilsson + + * acconfig.h: Remove. + * config.in: Regenerate. + +2006-06-13 Richard Earnshaw + + * configure: Regenerated. + +2006-06-05 Daniel Jacobowitz + + * configure: Regenerated. + +2006-05-31 Daniel Jacobowitz + + * configure: Regenerated. + +2006-03-07 Paul Brook + + * elfos.c (ARMul_OSHandleSWI): Call correct function for IsTTY. + +2006-02-01 Shaun Jackman + + * armos.c (ARMul_OSHandleSWI): Handle the RedBoot system + call meminfo. Return ENOSYS for unhandled RedBoot syscalls. + +2005-11-23 Mark Mitchell + + * wrapper.c (gdb/signals.h): Include it. + (SIGTRAP): Don't define. + (SIGBUS): Likewise. + (sim_stop_reason): Use TARGET_SIGNAL_* instead of SIG*. + +2005-11-16 Shaun Jackman + + * armos.c: Include limits.h + (unlink): Remove this macro. It is unused in this file and + conflicts with sim_callback->unlink. + (PATH_MAX): Define as 1024 if not already defined. + (ReadFileName): New function. + (SWIopen): Fix a potential buffer overflow. + (SWIremove): New function. + (SWIrename): Ditto. + (ARMul_OSHandleSWI): Handle the RDP calls SWI_IsTTY, + SWI_Remove, and SWI_Rename, as well as the RDI calls + AngelSWI_Reason_IsTTY, AngelSWI_Reason_Remove, and + AngelSWI_Reason_Rename. + +2005-09-19 Paul Brook + + * armdefs.h: Define ARMsword and ARMsdword. Use stdint.h when + available. + * armemu.c: Use them. + * armvirt.c (ARMul_MemoryInit): Use correct type for size. + * configure.ac: Check for stdint.h. + * config.in: Regenerate. + * configure: Regenerate. + +2005-05-24 Nick Clifton + + * thumbemu.c (handle_v6_thumb_insn): New function. + (ARMul_ThumbDecode): Call handle_v6_thumb_insn() when an undefined + instruction binary is encountered. + +2005-05-12 Nick Clifton + + * Update the address and phone number of the FSF organization in + the GPL notices in the following files: + COPYING, Makefile.in, armcopro.c, armdefs.h, armemu.c, + armemu.h, armfpe.h, arminit.c, armopts.h, armos.c, armos.h, + armrdi.c, armsupp.c, armvirt.c, bag.c, bag.h, communicate.c, + communicate.h, dbg_conf.h, dbg_cp.h, dbg_hif.h, dbg_rdi.h, + gdbhost.c, gdbhost.h, iwmmxt.c, iwmmxt.h, kid.c, main.c, + maverick.c, parent.c, thumbemu.c, wrapper.c + +2005-04-20 Nick Clifton + + * armemu.c (handle_v6_insn): New function - emulate a few of the + v6 instructions - the ones now generated by GCC. + (ARMulEmulate32): Call handle_v6_insn when a possible v6 insn is + found. + * armdefs.h (struct ARMul_State): Add new field: is_v6. + (ARM_v6_Prop): Define. + * arminit.c (ARMul_NewState): Initialise the v6 flag. + (ARMul_SelectProcessor): Determine if the v6 flag should be + set. + * wrapper.c (sim_create_inferior): For unknown architectures, + default to allowing the v6 instructions. + +2005-04-18 Nick Clifton + + * iwmmxt.c (WMAC, WMADD): Move casts from the LHS of an assignment + operator to the RHS. + (WSLL, WSRA, WSRL, WUNPCKEH, WUNPACKEL): Use ULL suffix to + indicate an unsigned long long constant. + +2005-03-23 Mark Kettenis + + * configure: Regenerate. + +2005-01-14 Andrew Cagney + + * configure.ac: Sinclude aclocal.m4 before common.m4. Add + explicit call to AC_CONFIG_HEADER. + * configure: Regenerate. + +2005-01-12 Andrew Cagney + + * configure.ac: Update to use ../common/common.m4. + * configure: Re-generate. + +2005-01-11 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +2005-01-07 Andrew Cagney + + * configure.ac: Rename configure.in, require autoconf 2.59. + * configure: Re-generate. + +2004-12-08 Hans-Peter Nilsson + + * configure: Regenerate for ../common/aclocal.m4 update. + +2004-06-28 Andrew Cagney + + * armemu.c: Rename ui_loop_hook to deprecated_ui_loop_hook. + +2003-12-29 Mark Mitchell + + * armos.c (fcntl.h): Do not include it. + (O_RDONLY): Do not define. + (O_WRONLY): Likewise. + (O_RDWR): Likewise. + (targ-vals.h): Include it. + (translate_open_mode): Use TARGET_O_* instead of O_*. + (SWIopen): Likewise. + * Makefile.in (armos.o): Depend on targ-vals.h. + +2003-04-13 Nick Clifton + + * armvirt.c (GetWord): Only call XScale_check_memacc if in XScale + mode. + (PutWord): Likewise. + +2003-03-30 Nick Clifton + + * configure.in (CON_FLAGS): Remove. + (COPRO): Unconditionally include iwmmxt.o. + * configure: Regenerate. + * Makefile.in (CON_FLAGS): Remove. + * armcopro.c: Remove use of __IWMMXT__ flag. + * wrapper.c: Likewise. + * armemu.c: Likewise. + Add explanatory comment for suppressed code. + +2003-03-27 Nick Clifton + + * armos.c (ARMul_OsHandleSWI): Catch SWIs for unhandled vectors. + +2003-03-27 Nick Clifton + + * configure.in: (CON_FLAGS): Define and intialise. + (COPRO): Add iwmmxt.o if configuring for XScale. + * configure: Regenerate. + * Makefile.in (iwmmxt.o): Add rule to build. + (COM_FLAGS): Define. + (ALL_FLAGS): Add CON_FLAGS. + * armcopro.c (ARMul_CoProInit): Initialise iWMMXt coprocessors. + * armdefs.h (struct ARMul_State): Add 'is_iWMMXt' field. + (ARM_iWMMXt_Prop): Define. + * armemu.c (ARMul_Emulate16): Intercept iWMMXt instructions and + pass to coprocessor. + * arminit.c (ARMul_NewState): Initialise 'is_iWMMXt'. + (ARMul_Abort): Catch branches through uninitialised vectors. + * armos.c (softevtorcode): Update comment. + (ARMul_OsInit): Use ARMUndefinedInstrV. + * wrapper.c (sim_create_inferior): Handle iWMMXt processor type. + (sim_store_register): Handle iWMMXt registers. + (sim_fetch_register): Handle iWMMXt registers. + * iwmmxt.h: New file. Exported iWMMXt coprocessor emulator + functions. + * iwmmxt.c: New file: iWMMXt emulator. + +2003-03-20 Nick Clifton + + * Contribute support for Cirrus Maverick ARM co-processor, + written by Aldy Hernandez and + Andrew Cagney : + + * maverick.c: New file: Support for Maverick floating point + co-processor. + * Makefile.in: Add maverick.o target. + * configure.in (COPRO): Add maverick.o. + * configure: Regenerate. + * armcopro.c (ARMul_CoProInit): Only initialise co-processors + available on target processor. Add code to initialse Maverick + co-processor support code. + * armdefs.h (ARMul_state): Add is_ep9312 field. + (ARM_ep9312_Prop): Define. + * armemu.h: Add prototypes for Maverick co-processor + functions. + * arminit.c (ARMul_SelectProcessor): Initialise the + co-processor support once the chip has been selected. + * wrapper.c: Add support for Maverick co-processor. + (init): Do not call ARMul_CoProInit. Delays this until the + chip has been selected. + +2003-03-02 Nick Clifton + + * armos.c (SWIWrite0): Catch big-endian bug when printing + characters. + +2003-02-27 Andrew Cagney + + * wrapper.c (sim_create_inferior, sim_open): Rename _bfd to bfd. + +2003-01-10 Ben Elliston + + * README.Cygnus: Rename from this .. + * README: .. to this. + +2002-09-27 Andrew Cagney + + * wrapper.c (sim_open): Add support for -m. + (mem_size): Reduce to 2MB. + Fix PR gdb/433. + +2002-08-15 Nick Clifton + + * armos.c (ARMul_OSHandleSWI): Catch and ignore SWIs of -1, they + can be caused by an interrupted system call being resumed by GDB. + +2002-07-05 Nick Clifton + + * armemu.c (ARMul_Emulate32): Add more tests for valid MIA, MIAPH + and MIAxy instructions. + +2002-06-21 Nick Clifton + + * armos.h (ADP_Stopped_RunTimeError): Set correct value. + +2002-06-16 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +2002-06-12 Andrew Cagney + + * Makefile.in: Update copyright. + (wrapper.o): Specify dependencies. + * wrapper.c: Include "gdb/sim-arm.h". + (sim_store_register, sim_fetch_register): Rewrite using `enum + arm_sim_regs' and a switch. + +2002-06-09 Andrew Cagney + + * wrapper.c: Include "gdb/callback.h" and "gdb/remote-sim.h". + * armos.c: Include "gdb/callback.h". + +2002-05-29 Nick Clifton + + * armcopro.c (XScale_check_memacc): Set the FSR and FAR registers + if a Data Abort is detected. + +2002-05-27 Nick Clifton + + * armvirt.c (GetWord): Only perform access checks if 'check' + is set. + (PutWord): Likewise. + * wrapper.c (sim_create_inferior): Report unknown machine + numbers. + * thumbemu.c (ARMul_ThumbDecode, Case 31): Do not set LR to pc + + 2, it has already been advanced. + +2002-05-23 Nick Clifton + + * thumbemu.c (ARMul_ThumbDecode): When decoding a BLX(1) + instruction do not add in the second bit of the base address - + this has already been accounted for. + +2002-05-21 Nick Clifton + + * armcopro.c (check_cp13_access): Allow access to register 1 when + CRm is 1. + (write_cp13_reg): Allow bit 0 of reg 1 of CRm 1 to be written to. + +2002-05-17 Nick Clifton + + * Makefile.in (SIM_TARGET_SWITCHES): Define. + * armos.c (swi_mask): Define. Initialise to supporting all + SWI emulations. + (ARMul_OSInit): For XScale targets, only support the ANGEL + SWI interface. (This is at the request if Intel). + (ARMul_OSHandleSWI): Examine swi_mask to see if a particular + SWI call should be emulated. + Do not fall through from AngelSWI_Reason_WriteC. + Propagate exit code from RedBoot Exit SWI. + * rdi-dgb.h (swi_mask): Prototype. + (SWI_MASK_DEMON, SWI_MASK_ANGEL, SWI_MASK_REDBOOT): Define. + * wrapper.c (sim_target_parse_command_line): New function. + Look for and handle --swi-support switch. + (sim_target_parse_arg_array): New function. Process an argv + array for parsing by sim_target_parse_command_line. + (sim_target_display_usage): New function. Describe syntax of + --swi-suppoort switch. + (sim_open): Add call to sim_target_parse_arg_array). + +2002-05-09 Nick Clifton + + * armos.c (ARMul_OSHandleSWI): Support the RedBoot SWI in ARM + mode and some of its system calls. + +2002-03-17 Anthony Green + + * wrapper.c (mem_size): Increase the default target memory to 8MB. + +2002-02-21 Keith Seitz + + * armos.c (SWIWrite0): Use generic host_callback mechanism + for supported OS functions "open", "close", "write", etc. + (SWIopen): Likewise. + (SWIread): Likewise. + (SWIwrite): Likewise. + (SWIflen): Likewise. + (ARMul_OSHandleSWI): Likewise. + +2002-02-05 Nick Clifton + + * wrapper.c (sim_create_inferior): Modify previous patch so that + it is only triggered for COFF format executables. + +2002-02-04 Nick Clifton + + * wrapper.c (sin_create_inferior): If a v5 architecture is + detected, assume it might be an XScale binary, since there is no + way to distinguish between the two in the COFF file format. + +2002-01-10 Nick Clifton + + * arminit.c (ARMul_Abort): Fix parameters passed to CPRead[13]. + * armemu.c (ARMul_Emulate32): Fix parameters passed to CPRead[13] + and CPRead[14]. + Fix formatting. Improve layout. + * armemu.h: Fix formatting. Improve layout. + +2002-01-09 Nick Clifton + + * wrapper.c (sim_fetch_register): If fetching more than 4 bytes + return zeroes in the other words. + General formatting tidy ups. + +2001-11-16 Ben Harris + + * Makefile.in (armemu32.o): Replace $< with autoconf recommended + $(srcdir)/.... + (armemu26.o): Ditto. + +2001-10-18 Nick Clifton + + * armemu.h (CP_ACCESS_ALLOWED): New macro. + Fix formatting. + * armcopro.c (read_cp14_reg): Make static. + (write_cp14_reg): Make static. + (check_cp13_access): Use CP_ACCESS_ALLOWED macro. + Fix formatting. + * armsupp.c (ARMul_LDC): Check CP_ACCESS_ALLOWED. + (ARMul_STC): Check CP_ACCESS_ALLOWED. + (ARMul_MCR): Check CP_ACCESS_ALLOWED. + (ARMul_MRC): Check CP_ACCESS_ALLOWED. + (ARMul_CDP): Check CP_ACCESS_ALLOWED. + Fix formatting. + * armemu.c (MCRR): Check CP_ACCESS_ALLOWED. Test Rd and Rn not + equal to 15. + (MRRC): Check CP_ACCESS_ALLOWED. Test Rd and Rn not equal to 15. + Fix formatting. + +2001-05-11 Nick Clifton + + * armemu.c (ARMul_Emulate32): Fix handling of XScale LDRD and STRD + instructions with post indexed addressing modes. + +2001-05-08 Jens-Christian Lache + + * armsupp.c (ARMul_FixCPSR): Check Mode not Bank in order to + determine rocesor mode. + +2001-04-18 matthew green + + * armcopro.c (write_cp15_reg): Set CHANGEMODE if endianness changes. + (read_cp15_reg): Make non-static. + (XScale_cp15_LDC): Update for write_cp15_reg() change. + (XScale_cp15_MCR): Likewise. + (XScale_cp15_write_reg): Likewise. + (XScale_check_memacc): New function. Check for breakpoints being + activated by memory accesses. Does not support the Branch Target + Buffer. + (XScale_set_fsr_far): New function. Set FSR and FAR for XScale. + (XScale_debug_moe): New function. Set the debug Method Of Entry, + if configured. + (write_cp14_reg): Reset count counter if requested. + * armdefs.h (struct ARMul_State): New members `LastTime' and + `CP14R0_CCD' used for the timer/counters. + (ARMul_CP13_R0_FIQ, ARMul_CP13_R0_IRQ, ARMul_CP13_R8_PMUS, + ARMul_CP14_R0_ENABLE, ARMul_CP14_R0_CLKRST, ARMul_CP14_R0_CCD, + ARMul_CP14_R0_INTEN0, ARMul_CP14_R0_INTEN1, ARMul_CP14_R0_INTEN2, + ARMul_CP14_R0_FLAG0, ARMul_CP14_R0_FLAG1, ARMul_CP14_R0_FLAG2, + ARMul_CP14_R10_MOE_IB, ARMul_CP14_R10_MOE_DB, ARMul_CP14_R10_MOE_BT, + ARMul_CP15_R1_ENDIAN, ARMul_CP15_R1_ALIGN, ARMul_CP15_R5_X, + ARMul_CP15_R5_ST_ALIGN, ARMul_CP15_R5_IMPRE, ARMul_CP15_R5_MMU_EXCPT, + ARMul_CP15_DBCON_M, ARMul_CP15_DBCON_E1, ARMul_CP15_DBCON_E0): New + defines for XScale registers. + (XScale_check_memacc, XScale_set_fsr_far, XScale_debug_moe): Prototype. + (ARMul_Emulate32, ARMul_Emulate26): Clean up function definition. + (ARMul_Emulate32): Handle the clock counter and hardware instruction + breakpoints. Call XScale_set_fsr_far() for software breakpoints and + software interrupts. + (LoadMult): Call XScale_set_fsr_far() for data aborts. + (LoadSMult): Likewise. + (StoreMult): Likewise. + (StoreSMult): Likewise. + * armemu.h (write_cp15_reg): Update prototype. + * arminit.c (ARMul_NewState): Initialise CP14R0_CCD and LastTime. + (ARMul_Abort): If XScale, check for FIQ and IRQ being enabled in CP13 + register 0. + * armvirt.c (GetWord): Call XScale_check_memacc(). + (PutWord): Likewise. + +2001-03-20 Nick Clifton + + * armvirt.c (ARMul_ReLoadInstr): Do not enable alignment checking + when loading unaligned thumb instructions. + +2001-03-06 Nick Clifton + + * thumbemu.c (ARMul_ThumbDecode): Delete label bo_blx2. + Compute destination address of BLX(1) instruction by + taking bit 1 from PC and not from bit 0 of the offset. + +2001-02-27 Nick Clifton + + * armvirt.c (GetWord): Add new parameter - check - to enable or + disable the alignment checking. + (PutWord): Add new parameter - check - to enable or disable the + alignment checking. + (ARMul_ReLoadInstr): Pass extra parameter to GetWord. + (ARMul_ReadWord): Pass extra parameter to GetWord. + (ARMul_WriteWord): Pass extra parameter to PutWord. + (ARMul_StoreHalfWord): Pass extra parameter to PutWord. + (ARMul_WriteByte): Pass extra parameter to GetWord. + (ARMul_SwapWord): Pass extra parameter to PutWord. + (ARMul_SafeReadByte): New Function: Read a byte but do not abort. + (ARMul_SafeWriteByte): New Function: Write a byte but do not abort. + + * armdefs.h: Add prototypes for ARMul_SafeReadByte and + ARMul_SafeWriteByte. + + * wrapper.c (sim_write): Use ARMul_SafeWriteByte. + (sim_read): Use ARMul_SafeReadByte. + + * armos.c (in_SWI_handler): Remove. + (SWIWrite0): Use ARMul_SafeReadByte. + (WriteCommandLineTo): Use ARMul_SafeWriteByte. + (SWIopen): Use ARMul_SafeReadByte. + (SWIread): Use ARMul_SafeWriteByte. + (SWIwrite): Use ARMul_SafeReadByte. + (ARMul_OSHandleSWI): Remove use of is_SWI_handler. + (ARMul_OSException): Remove use of is_SWI_handler. + +2001-02-16 Nick Clifton + + * armemu.c: Remove Prefetch abort for breakpoints. Instead set + the state to RESUME. + +2001-02-14 Nick Clifton + + * armemu.c: Add code to preserve processor mode when a prefetch + abort is signalled after processing a breakpoint. + + * wrapper.c (sim_create_inferior): Reset processor into ARM mode + for any machine type except the early ARMs. + +2001-02-13 Nick Clifton + + * armos.c (in_SWI_handler): New static variable. + (ARMul_OSHandleSWI): Set in_SWI_handler whilst emulating a SWI. + (ARMul_OSException): Ignore exceptions generated whilst emulating + a SWI. + +2001-02-12 Nick Clifton + + * armemu.h (NEGBRANCH): Fix defintion. + +2001-02-01 Nick Clifton + + * armemu.c (LoadSMult): Update base address register after + restoring register bank. + (StoreMult): Update base address register after restoring register + bank. + +2001-01-31 Nick Clifton + + * armvirt.c (PutWord): Detect installation of SWI vector. + (SWI_vector_installed): Define. + * armos.c (ARMul_OsInit): Reset SWI_vector_installed. + * armos.h (SWI_vector_installed): Declare. + * wrapper.c (SWI_vector_installed): Remove definition. + (sim_write): Remove check of SWI vector installation + +2000-12-18 Nick Clifton + + * armemu.c (ARMul_Emulate26): Fix test for StoreDouble + instruction. + +2000-12-10 Nick Clifton + + * armos.c (ARMul_OSHandleSWI): Add 0x91 as an FPE SWI. + +2000-12-07 Nick Clifton + + * armemu.c (ARMul_Emulate26): Detect double word load and + store instructions and call emulation routines. + (Handle_Load_Double): Emulate a double word load instruction. + (Handle_Store_Double): Emulate a double word store + instruction. + +2000-12-03 Nick Clifton + + * armos.c: Fix formatting. + (ARMul_OSHandleSWI): Suppress support of DEMON SWIs when in xscale + mode. + +2000-11-29 Nick Clifton + + * armdefs.h (State): Add 'v5e' and 'xscale' fields. + (ARM_v5e_Prop): Define. + (ARM_XScale_Prop): Define. + + * wrapper.c (sim_create_inferior): Select processor based on + machine number. + (SWI_vector_installed): New boolean. Set to true if the SWI + vector address is written to by the executable. + + * arminit.c (ARMul_NewState): Switch default to 32 bit mode. + (ARMul_SelectProcessor): Initialise v5e and xscale signals. + (ARMul_Abort): Fix calculation of LR address. + + * armos.c (ARMul_OSHandleSWI): If a SWI vector has been installed + and a SWI is not handled by the simulator, pass the SWI off to the + vector, otherwise issue a warning message and continue. + + * armsupp.c (ARMul_CPSRAltered): Set S bit aswell. + + * thumbemu.c: Add v5 instruction simulation. + * armemu.c: Add v5, XScale and El Segundo instruction simulation. + + * armcopro.c: Add XScale co-processor emulation. + * armemu.h: Add exported XScale co-processor functions. + +2000-09-15 Nick Clifton + + * armdefs.h: Rename StrongARM property to v4_ARM and add v5 ARM + property. Delete unnecessary processor names. + (ARM_Strong_Prop): Delete. + (STRONGARM): Delete. + (ARM_v4_Prop): Add. + (ARM_v5_Prop): Add + (State): Delete is_StrongARM boolean. Add is_v4 and is_v5 + booleans. + + * armemu.h (BUSUSEDINCPCS): Use is_v4 boolean. + (BUSUSEDINCPCN): Use is_v4 boolean. + + * arminit.c (ARMul_NewState): Initialise is_v4 and is_v5 fields. + (ARMul_SelectProcessor): Change second parameter from 'processor' + to 'properties'. Set is_v4 and is_v5 booleans in State. + + * armrdi.c: Remove use of ARM processor names. Replace with ARM + processor properties. + + * wrapper.c (sim_create_inferior): Choose properties passed to + ARMul_SelectProcessor based on machine number. + +2000-08-14 Nick Clifton + + * armemu.c (LHPOSTDOWN): Compute write back value before + performing load in case the offset register is overwritten. + (LHPOSTUP): Ditto. + +2000-07-14 Fernando Nasser + + * wrapper.c (sim_create_inferior): Fix typo in the previous patch. + +2000-07-14 Fernando Nasser + + * wrapper.c (sim_create_inferior): Reset mode to ARM when creating a + new inferior. + +2000-07-04 Alexandre Oliva + + * armvirt.c (ABORTS): Do not define. + + * armdefs.h (struct ARMul_State): Add is_StrongARM. + (ARM_Strong_Prop, STRONGARM): Define. + * arminit.c (ARMul_NewState): Reset is_StrongARM. + (ARMul_SelectProcessor): Set is_StrongARM. + * wrapper.c (sim_create_inferior): Use bfd machine type to + determine processor type to emulate. + * armemu.h (BUSUSEDINCPCS, BUSUSEDINCPCN): Don't increment PC + when emulating StrongARM. + + * armemu.c (ARMul_Emulate, t_undefined): Proceed to next insn. + + * armemu.h (INSN_SIZE): New macro. + (SET_ABORT): Save CPSR in SPSR and set LR. + * armemu.c (ARMul_Emulate, isize): Set to INSN_SIZE. + (WriteR15, WriteSR15): Do not discard bit 1 in Thumb mode. + * arminit.c (ARMul_Abort): Use new SETABORT and INSN_SIZE. + + * armemu.c (LoadSMult): Use WriteR15() to discard the least + significant bits of PC. + + * armemu.h (WRITEDESTB): New macro. + * armemu.c (ARMul_Emulate26, bl): Use WriteR15Branch() to + modify PC. Moved the existing logic... + (WriteR15Branch): ... here. New function. + (WriteR15, WriteSR15): Drop the two least significant bits. + (LoadSMult): Use WriteR15Branch() to modify PC. + (LoadMult): Use WRITEDESTB() instead of WRITEDEST(). + + * armemu.h (GETSPSR): Call ARMul_GetSPSR(). + * armsupp.c (ARMul_CPSRAltered): Zero out bits as they're + extracted from state->Cpsr, but preserve the unused bits. + (ARMul_GetCPSR): Get bits preserved in state->Cpsr. + (ARMul_GetSPSR, ARMul_FixCPSR): Use ARMul_GetCPSR() to + get the full CPSR word. + + * armemu.h (PSR_FBITS, PSR_SBITS, PSR_XBITS, PSR_CBITS): New. + (SETPSR_F, SETPSR_S, SETPSR_X, SETPSR_C): New macros. + (SETPSR, SET_INTMODE, SETCC): Removed. + * armsupp.c (ARMul_FixCPSR, ARMul_FixSPSR): Do not test bit + mask. Use SETPSR_* to modify PSR. + (ARMul_SetCPSR): Load all bits from value. + * armemu.c (ARMul_Emulate, msr): Do not test bit mask. + + * armemu.c (ARMul_Emulate): Compute writeback value before + loading, since the offset register may be the destination + register. + + * armdefs.h (SYSTEMBANK): Define as USERBANK. + * armsupp.c (ARMul_SwitchMode): Remove SYSTEMBANK cases. + +2000-06-22 Alexandre Oliva + + * armemu.c (Multiply64): Fix computation of flag N. + + * armemu.c (MultiplyAdd64): Fix computation of flag N. + +2000-06-20 Alexandre Oliva + + * armemu.h (NEGBRANCH): Do not overwrite the two most significant + bits of the offset. + +2000-05-25 Nick Clifton + + * armcopro.c (MMUMCR): Only indicate mode change if a singal has + really changed. + (MMUWrite): Only indicate mode change if a singal has really + changed. + + * armdefs.h (SYSTEMMODE): Define. + (BANK_CAN_ACEESS_SPSR): Define. + + * armemu.c (ARM_Emulate26): If the mode has changed allow the PC + to advance before stopping the emulation. + + * arminit.c (ARMul_Reset): Ensure Mode field of State is set + correctly. + + * armos.c (ARMul_OSInit): Create a initial stack pointer for + System mode. + + * armsupp.c (ModeToBank): Remove unused first parameter. + Add support for System Mode. + (ARMul_GetSPSR): Use BANK_CAN_ACCESS_SPSR macro. + (ARMul_SetSPSR): Use BANK_CAN_ACCESS_SPSR macro. + (ARMul_FixSPSR): Use BANK_CAN_ACCESS_SPSR macro. + (ARMulSwitchMode): Add support for System Mode. + +Wed May 24 14:40:34 2000 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +2000-05-23 Nick Clifton + + * wrapper.c (sim_store_register): Special handling for CPSR + register. + +2000-03-11 Philip Blundell + + * armemu.c (LoadSMult, LoadMult): Correct handling of aborts. + Patch from Allan Skillman . + +Wed Mar 22 15:24:21 2000 glen mccready + + * wrapper.c (sim_open,sim_close): Copy into myname, free myname. + +2000-02-08 Nick Clifton + + * wrapper.c: Fix compile time warning messages. + * armcopro.c: Fix compile time warning messages. + * armdefs.h: Fix compile time warning messages. + * armemu.c: Fix compile time warning messages. + * armemu.h: Fix compile time warning messages. + * armos.c: Fix compile time warning messages. + * armsupp.c: Fix compile time warning messages. + * armvirt.c: Fix compile time warning messages. + * bag.c: Fix compile time warning messages. + +2000-02-02 Bernd Schmidt + + * *.[ch]: Use indent to make readable. + +1999-11-22 Nick Clifton + + * armos.c (SWIread): Generate an error message if a huge read is + performed. + (SWIwrite): Generate an error message if a huge write is + performed. + +1999-10-27 Nick Clifton + + * thumbemu.c (ARMul_ThumbDecode): Accept 0xbebe as a thumb + breakpoint. + +1999-10-08 Ulrich Drepper + + * armos.c (SWIopen): Always pass third parameter with 0666 since + otherwise uninitialized memory gets access if the O_CREAT bit is + set and so we possibly cannot access the file afterwards. + +1999-09-29 Doug Evans + + * armos.c (SWIWrite0): Send output to stdout instead of stderr. + (ARMul_OSHandleSWI, case SWI_WriteC,AngelSWI_Reason_WriteC): Ditto. + +Thu Sep 2 18:15:53 1999 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +1999-05-08 Felix Lee + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +1999-04-06 Keith Seitz + + * wrapper.c (stop_simulator): New global. + (sim_stop): Set sim state to STOP and set + stop_simulator. + (sim_resume): Reset stop_simulator. + (sim_stop_reason): If stop_simulator is set, tell gdb + that the we took SIGINT. + * armemu.c (ARMul_Emulate26): Don't loop forever. Stop if + stop_simulator is set. + +1999-04-02 Keith Seitz + + * armemu.c (ARMul_Emulate26): If NEED_UI_LOOP_HOOK, call ui_loop_hook + whenever the counter expires. + * Makefile.in (SIM_EXTRA_CFLAGS): Include define NEED_UI_LOOP_HOOK. + +1999-03-24 Nick Clifton + + * armemu.c (ARMul_Emulate26): Handle new breakpoint value. + * thumbemu.c (ARMul_ThumbDecode): Handle new breakpoint value. + +Mon Sep 14 09:00:05 1998 Nick Clifton + + * wrapper.c (sim_open): Set endianness according to BFD or command + line switch. + + * tconfig.in: Define SIM_HAVE_BIENDIAN. + +Thu Aug 27 11:00:05 1998 Nick Clifton + + * armemu.c (Multiply64): Test for Rm (rather than Rs) not being + the same as either RdHi or RdLo. + +Thu Jul 2 10:24:35 1998 Nick Clifton + + * armos.c (ARMul_OSHandleSWI: AngelSWI_Reason_ReportException): + Set Reg[0] based on reason for for the exception. + +Thu Jun 4 15:22:03 1998 Jason Molenda (crash@bugshack.cygnus.com) + + * armos.c (SWIwrite0): New function. + (WriteCommandLineTo): New function. + (SWIopen): New function. + (SWIread): New function. + (SWIwrite): New function. + (SWIflen): New function. + (ARMul_OSHandleSWI): Call new functions instead of handling + these here. + (ARMul_OSHandleSWI): Handle Angel SWIs correctly. + (*): Reformat spacing to be a bit more GNUly. + Most code taken from a patch by Anthony Thompson + (athompso@cambridge.arm.com) + +Tue Jun 2 15:22:22 1998 Nick Clifton + + * armos.h: Add Angel SWI and its reason codes. + * armos.c (ARMul_OSHandleSWI): Ignore Angel SWIs (for now). + +Mon Jun 1 17:14:19 1998 Anthony Thompson (athompso@cambridge.arm.com) + + * armos.c (ARMul_OSHandleSWI::SWI_Open): Handle special case + of ":tt" to catch stdin in addition to stdout. + (ARMul_OSHandleSWI::SWI_Seek): Return 0 or 1 to indicate failure + or success of lseek(). + +Wed May 20 17:36:25 1998 Nick Clifton + + * armos.c (ARMul_OSHandleSWI): Special case code to catch attempts + to open stdout. + +Wed Apr 29 15:29:55 1998 Jeff Johnston + + * armos.c (ARMul_OSHandleSWI): Added code for SWI_Clock, + SWI_Flen, and SWI_Time. Also fixed SWI_Seek code to only + seek from offset 0 and not to use R2 for whence since it is + not passed as part of the SWI call. + +Tue Apr 28 18:33:31 1998 Geoffrey Noer + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +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:26 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:20:19 1998 Tom Tromey + + * configure.in: Don't call sinclude. + +Sat Apr 4 20:36:25 1998 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Fri Mar 27 16:15:52 1998 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Mar 25 12:35:29 1998 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Mar 18 12:38:12 1998 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Tue Mar 10 09:26:38 1998 Nick Clifton + + * armopts.h: Remove definition of LITTLEND - it is not used. + +Tue Feb 17 12:35:54 1998 Andrew Cagney + + * wrapper.c (sim_store_register, sim_fetch_register): Pass in + length parameter. Return -1. + +Sun Feb 1 16:47:51 1998 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Sat Jan 31 18:15:41 1998 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Jan 19 22:26:29 1998 Doug Evans + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Dec 15 23:17:11 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Tue Dec 9 11:30:48 1997 Nick Clifton + + * Makefile.in: Updated with changes from branch. + * armdefs.h: ditto + * armemu.c: ditto these changes + * armemu.h: ditto add support for + * armos.c: ditto the Thumb instruction + * armsupp.c: ditto set and the new v4 + * armvirt.c: ditto architecture. + * wrapper.c: ditto + * thumbemu.c: New file from branch. + + +Thu Dec 4 09:21:05 1997 Doug Evans + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Thu Oct 30 13:54:06 1997 Nick Clifton + + * armos.c (ARMul_OSHandleSWI): Add support for GetEnv SWI. Patch + from Tony Thompson at ARM: athompso@arm.com + + * wrapper.c (sim_create_inferior): Add code to create an execution + environment. Patch from Tony Thompson at ARM: athompso@arm.com + +Wed Oct 22 14:43:00 1997 Andrew Cagney + + * wrapper.c (sim_load): Pass lma_p and sim_write args to + sim_load_file. + +Fri Oct 3 09:28:00 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Sep 24 17:38:57 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Tue Sep 23 11:04:38 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Sep 22 11:46:20 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Fri Sep 19 17:45:25 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Sep 15 17:36:15 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Thu Sep 4 17:21:23 1997 Doug Evans + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Aug 27 18:13:22 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Tue Aug 26 10:37:27 1997 Andrew Cagney + + * wrapper.c (sim_kill): Delete. + (sim_create_inferior): Add ABFD argument. + (sim_load): Move setting of PC from here. + (sim_create_inferior): To here. + +Mon Aug 25 17:50:22 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Mon Aug 25 15:35:45 1997 Andrew Cagney + + * wrapper.c (sim_open): Add ABFD argument. + +Tue May 20 10:13:26 1997 Andrew Cagney + + * wrapper.c (sim_open): Add callback argument. + (sim_set_callbacks): Drop SIM_DESC argument. + +Thu Apr 24 00:39:51 1997 Doug Evans + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Fri Apr 18 13:32:23 1997 Andrew Cagney + + * wrapper.c (sim_stop): Stub sim_stop function. + +Thu Apr 17 18:33:01 1997 Fred Fish + + * arminit.c (ARMul_NewState): Preinitialize the state to + all zero/NULL. + +Thu Apr 17 02:39:02 1997 Doug Evans + + * Makefile.in (SIM_OBJS): Add sim-load.o. + * wrapper.c (sim_kind,myname): New static locals. + (sim_open): Set sim_kind, myname. + (sim_load): Call sim_load_file to do work. Set start address from bfd. + (sim_create_inferior): Return SIM_RC. Delete start_address arg. + +Thu Apr 17 11:48:25 1997 Andrew Cagney + + * wrapper.c (sim_trace): Update so that it matches prototype. + +Mon Apr 7 15:45:02 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + * config.in: Ditto. + +Mon Apr 7 12:01:17 1997 Andrew Cagney + + * Makefile.in (armemu32.o): Replace $< with autoconf recommended + $(srcdir)/.... + (armemu26.o): Ditto. + +Wed Apr 2 15:06:28 1997 Doug Evans + + * wrapper.c (sim_open): New arg `kind'. + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Apr 2 14:50:44 1997 Ian Lance Taylor + + * COPYING: Update FSF address. + +Wed Apr 2 14:34:19 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Wed Mar 19 01:14:00 1997 Andrew Cagney + + * configure: Regenerated to track ../common/aclocal.m4 changes. + +Mon Mar 17 15:10:07 1997 Andrew Cagney + + * configure: Re-generate. + +Fri Mar 14 10:34:11 1997 Michael Meissner + + * configure: Regenerate to track ../common/aclocal.m4 changes. + +Thu Mar 13 12:38:56 1997 Doug Evans + + * wrapper.c (sim_open): Has result now. + (sim_*): New SIM_DESC argument. + +Tue Feb 4 13:22:21 1997 Doug Evans + + * Makefile.in (@COMMON_MAKEFILE_FRAG@): Use + COMMON_{PRE,POST}_CONFIG_FRAG instead. + * configure.in: sinclude ../common/aclocal.m4. + * configure: Regenerated. + +Thu Jan 23 11:46:23 1997 Stu Grossman (grossman@critters.cygnus.com) + + * configure configure.in Makefile.in: Update to new configure + scheme which is more compatible with WinGDB builds. + * configure.in: Improve comment on how to run autoconf. + * configure: Re-run autoconf to get new ../common/aclocal.m4. + * Makefile.in: Use autoconf substitution to install common + makefile fragment. + +Wed Nov 20 01:05:10 1996 Doug Evans + + * run.c: Deleted, use one in ../common now. + * Makefile.in: Delete everything that's been moved to + ../common/Make-common.in. + (SIM_OBJS): Define. + * configure.in: Simplify using macros in ../common/aclocal.m4. + * configure: Regenerated. + * config.in: New file. + * armos.c: #include config.h. + * wrapper.c (mem_size): Value is in bytes now. + (sim_callback): New global. + (arm_sim_set_profile{,_size}): Delete. + (arm_sim_set_mem_size): Rename to sim_size. + (sim_do_command): Call printf_filtered via callback. + (sim_set_callbacks): Record callback. + +Thu Oct 3 16:10:27 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * Makefile.in (mostlyclean): Remove config.log. + +Wed Jun 26 12:17:24 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * Makefile.in (bindir, libdir, datadir, mandir, infodir, includedir, + INSTALL_PROGRAM, INSTALL_DATA): Use autoconf-set values. + (docdir): Removed. + * configure.in (AC_PREREQ): autoconf 2.5 or higher. + (AC_PROG_INSTALL): Added. + * configure: Rebuilt. + +Wed Feb 21 12:14:31 1996 Ian Lance Taylor + + * configure: Regenerate with autoconf 2.7. + +Fri Dec 15 16:27:30 1995 Ian Lance Taylor + + * run.c (main): Use new bfd_big_endian macro. + +Mon Nov 20 17:40:38 1995 Doug Evans + + * run.c: Include "getopt.h". + (verbose): Delete. + (usage): Make static. + (main): Call arm_sim_set_verbosity. + Only load sections marked SEC_LOAD. + * wrapper.c (mem_size, verbosity): New static global. + (arm_sim_set_mem_size): Renamed from sim_size. Callers updated. + (arm_sim_set_profile{,_size}): Renamed from sim_foo. Callers updated. + +Fri Nov 17 19:35:11 1995 Doug Evans + + * armdefs.h (ARMul_State): New member `verbose'. + * armrdi.c (ARMul_ConsolePrint): Add missing va_end. + * run.c (verbose): Make global. + * wrapper.c (init): Set state->verbose. + (ARMul_ConsolePrint): Don't print anything if !verbose. + +Fri Oct 13 15:30:30 1995 Doug Evans + + * armos.c: #include dbg_rdi.h. + (ARMul_OSHandleSWI): Handle SWI_Breakpoint. + * armos.h (SWI_Breakpoint): Define. + * wrapper.c: #include armemu.h, dbg_rdi.h. + (rc): Delete. + (sim_resume): Use state->EndCondition to record stop state. + Call FLUSHPIPE before returning. + (sim_stop_reason): Determine reason from state->EndCondition. + +Fri Oct 13 15:04:05 1995 steve chamberlain + + * wrapper.c (sim_set_callbacks): New. + +Thu Sep 28 19:45:56 1995 Doug Evans + + * armos.c (ARMul_OSHandleSWI): Result of read/write calls is + number of bytes not read/written (or -1). + +Wed Sep 20 13:35:54 1995 Ian Lance Taylor + + * Makefile.in (maintainer-clean): New synonym for realclean. + +Fri Sep 8 14:27:20 1995 Ian Lance Taylor + + * configure.in: Remove AC_PROG_INSTALL. + * configure: Rebuild. + * Makefile.in (INSTALL): Revert to using install.sh. + (INSTALL_PROGRAM, INSTALL_DATA): Set to $(INSTALL). + (INSTALL_XFORM, INSTALL_XFORM1): Restore. + (mostlyclean): Make the same as clean, not distclean. + (clean): Remove config.log. + (install): Don't install in $(tooldir). + +Thu Sep 7 12:00:17 1995 Doug Evans + + (Try to) Update to new bfd autoconf scheme. + * run.c: Don't include sysdep.h. + * Makefile.in (INSTALL{,_PROGRAM,_DATA}): Use autoconf computed value. + (CC, CFLAGS, AR, RANLIB): Likewise. + (HDEFINES, TDEFINES): Define. + (CC_FOR_BUILD): Delete. + (host_makefile_frag): Delete. + (Makefile): Don't depend on frags. + * configure.in (sysdep.h): Don't create symlink. + (host_makefile_frag, frags): Deleted. + (CC, CFLAGS, AR, RANLIB, INSTALL): Compute values. + * configure: Regenerated. + +Thu Aug 3 10:45:37 1995 Fred Fish + + * Update all FSF addresses except those in COPYING* files. + +Wed Jul 5 16:15:54 1995 J.T. Conklin + + * Makefile.in (clean): Remove run, libsim.a. + + * Makefile.in, configure.in: converted to autoconf. + * configure: New file, generated with autconf 2.4. + + * arm.mt: Removed. + +Fri Jun 30 16:49:47 1995 Stan Shebs + + * wrapper.c (sim_do_command): New function. + +Tue Jun 13 10:57:32 1995 Steve Chamberlain + + * armos.c (ARMul_OSHandleSWI): New version to work with + newlib simply. + +Thu Jun 8 14:37:14 1995 Steve Chamberlain + + * run.c (main): Grab return value from right register. + +Wed May 24 14:37:31 1995 Steve Chamberlain + + * New. + +
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: kid.c =================================================================== --- kid.c (nonexistent) +++ kid.c (revision 816) @@ -0,0 +1,540 @@ +/* kid.c -- ARMulator RDP/RDI interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/*****************************************************************/ +/* The child process continues here... */ +/* It waits on a pipe from the parent and translates the RDP */ +/* messages into RDI calls to the ARMulator passing RDP replies */ +/* back up a pipe to the parent. */ +/*****************************************************************/ + +#include +#include + +#include "armdefs.h" +#include "dbg_conf.h" +#include "dbg_hif.h" +#include "dbg_rdi.h" +#include "gdbhost.h" +#include "communicate.h" + +/* The pipes between the two processes */ +extern int mumkid[2]; +extern int kidmum[2]; + +/* The maximum number of file descriptors */ +extern int nfds; + +/* The machine name */ +#define MAXHOSTNAMELENGTH 64 +extern char localhost[MAXHOSTNAMELENGTH + 1]; + +/* The socket number */ +extern unsigned int socketnumber; + +/* RDI interface */ +extern const struct RDIProcVec armul_rdi; + +static int MYrdp_level = 0; + +static int rdi_state = 0; + +/**************************************************************/ +/* Signal handler that terminates excecution in the ARMulator */ +/**************************************************************/ +void +kid_handlesignal (int sig) +{ +#ifdef DEBUG + fprintf (stderr, "Terminate ARMulator excecution\n"); +#endif + if (sig != SIGUSR1) + { + fprintf (stderr, "Unsupported signal.\n"); + return; + } + armul_rdi.info (RDISignal_Stop, (unsigned long *) 0, (unsigned long *) 0); +} + +/********************************************************************/ +/* Waits on a pipe from the socket demon for RDP and */ +/* acts as an RDP to RDI interpreter on the front of the ARMulator. */ +/********************************************************************/ +void +kid () +{ + char *p, *q; + int i, j, k; + long outofthebag; + unsigned char c, d, message; + ARMword x, y, z; + struct sigaction action; + PointHandle point; + Dbg_ConfigBlock config; + Dbg_HostosInterface hostif; + struct Dbg_MCState *MCState; + char command_line[256]; + struct fd_set readfds; + + /* Setup a signal handler for SIGUSR1 */ + action.sa_handler = kid_handlesignal; + action.sa_mask = 0; + action.sa_flags = 0; + + sigaction (SIGUSR1, &action, (struct sigaction *) 0); + + while (1) + { + /* Wait for ever */ + FD_ZERO (&readfds); + FD_SET (mumkid[0], &readfds); + + i = select (nfds, &readfds, + (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); + + if (i < 0) + { + perror ("select"); + } + + if (read (mumkid[0], &message, 1) < 1) + { + perror ("read"); + } + + switch (message) + { + case RDP_Start: + /* Open and/or Initialise */ + BAG_newbag (); + + MYread_char (mumkid[0], &c); /* type */ + MYread_word (mumkid[0], &x); /* memorysize */ + if (c & 0x2) + MYread_char (mumkid[0], &d); /* speed */ + config.processor = 0; + config.memorysize = x; + config.bytesex = (c & 0x4) ? RDISex_Big : RDISex_Little; + if (c & 0x8) + config.bytesex = RDISex_DontCare; + + hostif.dbgprint = myprint; + hostif.dbgpause = mypause; + hostif.dbgarg = stdout; + hostif.writec = mywritec; + hostif.readc = myreadc; + hostif.write = mywrite; + hostif.gets = mygets; + hostif.reset = mypause; /* do nothing */ + hostif.resetarg = "Do I love resetting or what!\n"; + + if (rdi_state) + { + /* we have restarted, so kill off the existing run. */ + /* armul_rdi.close(); */ + } + i = armul_rdi.open (c & 0x3, &config, &hostif, MCState); + rdi_state = 1; + + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], (unsigned char) i); + + x = ~0x4; + armul_rdi.info (RDIVector_Catch, &x, 0); + + break; + + case RDP_End: + /* Close and Finalise */ + i = armul_rdi.close (); + rdi_state = 0; + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDP_Read: + /* Read Memory Address */ + MYread_word (mumkid[0], &x); /* address */ + MYread_word (mumkid[0], &y); /* nbytes */ + p = (char *) malloc (y); + i = armul_rdi.read (x, p, (unsigned *) &y); + MYwrite_char (kidmum[1], RDP_Return); + for (k = 0; k < y; k++) + MYwrite_char (kidmum[1], p[k]); + free (p); + MYwrite_char (kidmum[1], (unsigned char) i); + if (i) + MYwrite_word (kidmum[1], y); /* number of bytes sent without error */ + break; + + case RDP_Write: + /* Write Memory Address */ + MYread_word (mumkid[0], &x); /* address */ + MYread_word (mumkid[0], &y); /* nbytes */ + p = (char *) malloc (y); + for (k = 0; k < y; k++) + MYread_char (mumkid[0], &p[k]); + i = armul_rdi.write (p, x, (unsigned *) &y); + free (p); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], (unsigned char) i); + if (i) + MYwrite_word (kidmum[1], y); /* number of bytes sent without error */ + break; + + case RDP_CPUread: + /* Read CPU State */ + MYread_char (mumkid[0], &c); /* mode */ + MYread_word (mumkid[0], &x); /* mask */ + p = (char *) malloc (4 * RDINumCPURegs); + i = armul_rdi.CPUread (c, x, (ARMword *) p); + MYwrite_char (kidmum[1], RDP_Return); + for (k = 1, j = 0; k != 0x80000000; k *= 2) + if (k & x) + MYwrite_word (kidmum[1], ((ARMword *) p)[j++]); + free (p); + if (i) + MYwrite_char (kidmum[1], (unsigned char) j); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDP_CPUwrite: + /* Write CPU State */ + MYread_char (mumkid[0], &c); /* mode */ + MYread_word (mumkid[0], &x); /* mask */ + + p = (char *) malloc (4 * RDINumCPURegs); + for (k = 1, j = 0; k != 0x80000000; k *= 2) + if (k & x) + MYread_word (mumkid[0], &(((ARMword *) p)[j++])); + i = armul_rdi.CPUwrite (c, x, (ARMword *) p); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], (unsigned char) i); + free (p); + break; + + case RDP_CPread: + /* Read Co-Processor State */ + MYread_char (mumkid[0], &c); /* CPnum */ + MYread_word (mumkid[0], &x); /* mask */ + p = q = (char *) malloc (16 * RDINumCPRegs); + i = armul_rdi.CPread (c, x, (ARMword *) p); + MYwrite_char (kidmum[1], RDP_Return); + for (k = 1, j = 0; k != 0x80000000; k *= 2, j++) + if (k & x) + { + if ((c == 1 || c == 2) && k <= 128) + { + MYwrite_FPword (kidmum[1], q); + q += 16; + } + else + { + MYwrite_word (kidmum[1], *q); + q += 4; + } + } + free (p); + if (i) + MYwrite_char (kidmum[1], (unsigned char) j); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDP_CPwrite: + /* Write Co-Processor State */ + MYread_char (mumkid[0], &c); /* CPnum */ + MYread_word (mumkid[0], &x); /* mask */ + p = q = (char *) malloc (16 * RDINumCPURegs); + for (k = 1, j = 0; k != 0x80000000; k *= 2, j++) + if (k & x) + { + if ((c == 1 || c == 2) && k <= 128) + { + MYread_FPword (kidmum[1], q); + q += 16; + } + else + { + MYread_word (mumkid[0], (ARMword *) q); + q += 4; + } + } + i = armul_rdi.CPwrite (c, x, (ARMword *) p); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], (unsigned char) i); + free (p); + break; + + case RDP_SetBreak: + /* Set Breakpoint */ + MYread_word (mumkid[0], &x); /* address */ + MYread_char (mumkid[0], &c); /* type */ + if ((c & 0xf) >= 5) + MYread_word (mumkid[0], &y); /* bound */ + i = armul_rdi.setbreak (x, c, y, &point); + if (!MYrdp_level) + BAG_putpair ((long) x, (long) point); + MYwrite_char (kidmum[1], RDP_Return); + if (MYrdp_level) + MYwrite_word (kidmum[1], point); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDP_ClearBreak: + /* Clear Breakpoint */ + MYread_word (mumkid[0], &point); /* PointHandle */ + if (!MYrdp_level) + { + BAG_getsecond ((long) point, &outofthebag); /* swap pointhandle for address */ + BAG_killpair_byfirst (outofthebag); + point = outofthebag; + } + i = armul_rdi.clearbreak (point); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDP_SetWatch: + /* Set Watchpoint */ + MYread_word (mumkid[0], &x); /* address */ + MYread_char (mumkid[0], &c); /* type */ + MYread_char (mumkid[0], &d); /* datatype */ + if ((c & 0xf) >= 5) + MYread_word (mumkid[0], &y); /* bound */ + i = armul_rdi.setwatch (x, c, d, y, &point); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_word (kidmum[1], point); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDP_ClearWatch: + /* Clear Watchpoint */ + MYread_word (mumkid[0], &point); /* PointHandle */ + i = armul_rdi.clearwatch (point); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDP_Execute: + /* Excecute */ + + MYread_char (mumkid[0], &c); /* return */ + +#ifdef DEBUG + fprintf (stderr, "Starting execution\n"); +#endif + i = armul_rdi.execute (&point); +#ifdef DEBUG + fprintf (stderr, "Completed execution\n"); +#endif + MYwrite_char (kidmum[1], RDP_Return); + if (c & 0x80) + MYwrite_word (kidmum[1], point); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDP_Step: + /* Step */ + MYread_char (mumkid[0], &c); /* return */ + MYread_word (mumkid[0], &x); /* ninstr */ + point = 0x87654321; + i = armul_rdi.step (x, &point); + MYwrite_char (kidmum[1], RDP_Return); + if (c & 0x80) + MYwrite_word (kidmum[1], point); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDP_Info: + /* Info */ + MYread_word (mumkid[0], &x); + switch (x) + { + case RDIInfo_Target: + i = armul_rdi.info (RDIInfo_Target, &y, &z); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_word (kidmum[1], y); /* Loads of info... */ + MYwrite_word (kidmum[1], z); /* Model */ + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDISet_RDILevel: + MYread_word (mumkid[0], &x); /* arg1, debug level */ + i = armul_rdi.info (RDISet_RDILevel, &x, 0); + if (i == RDIError_NoError) + MYrdp_level = x; + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDISet_Cmdline: + for (p = command_line; MYread_char (mumkid[0], p), *p; p++) + ; /* String */ + i = armul_rdi.info (RDISet_Cmdline, + (unsigned long *) command_line, 0); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDIInfo_Step: + i = armul_rdi.info (RDIInfo_Step, &x, 0); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_word (kidmum[1], x); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + case RDIVector_Catch: + MYread_word (mumkid[0], &x); + i = armul_rdi.info (RDIVector_Catch, &x, 0); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], i); + break; + + case RDIInfo_Points: + i = armul_rdi.info (RDIInfo_Points, &x, 0); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_word (kidmum[1], x); + MYwrite_char (kidmum[1], (unsigned char) i); + break; + + default: + fprintf (stderr, "Unsupported info code %d\n", x); + break; + } + break; + + case RDP_OSOpReply: + /* OS Operation Reply */ + MYwrite_char (kidmum[1], RDP_Fatal); + break; + + case RDP_Reset: + /* Reset */ + for (i = 0; i < 50; i++) + MYwrite_char (kidmum[1], RDP_Reset); + p = (char *) malloc (MAXHOSTNAMELENGTH + 5 + 20); + sprintf (p, "Running on %s:%d\n", localhost, socketnumber); + MYwrite_string (kidmum[1], p); + free (p); + + break; + default: + fprintf (stderr, "Oh dear: Something is seriously wrong :-(\n"); + /* Hmm.. bad RDP operation */ + break; + } + } +} + + +/* Handles memory read operations until an OS Operation Reply Message is */ +/* encounterd. It then returns the byte info value (0, 1, or 2) and fills */ +/* in 'putinr0' with the data if appropriate. */ +int +wait_for_osreply (ARMword * reply) +{ + char *p, *q; + int i, j, k; + unsigned char c, d, message; + ARMword x, y, z; + struct sigaction action; + PointHandle point; + Dbg_ConfigBlock config; + Dbg_HostosInterface hostif; + struct Dbg_MCState *MCState; + char command_line[256]; + struct fd_set readfds; + +#ifdef DEBUG + fprintf (stderr, "wait_for_osreply ().\n"); +#endif + + /* Setup a signal handler for SIGUSR1 */ + action.sa_handler = kid_handlesignal; + action.sa_mask = 0; + action.sa_flags = 0; + + sigaction (SIGUSR1, &action, (struct sigaction *) 0); + + while (1) + { + /* Wait for ever */ + FD_ZERO (&readfds); + FD_SET (mumkid[0], &readfds); + + i = select (nfds, &readfds, + (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); + + if (i < 0) + { + perror ("select"); + } + + if (read (mumkid[0], &message, 1) < 1) + { + perror ("read"); + } + + switch (message) + { + case RDP_Read: + /* Read Memory Address */ + MYread_word (mumkid[0], &x); /* address */ + MYread_word (mumkid[0], &y); /* nbytes */ + p = (char *) malloc (y); + i = armul_rdi.read (x, p, (unsigned *) &y); + MYwrite_char (kidmum[1], RDP_Return); + for (k = 0; k < y; k++) + MYwrite_char (kidmum[1], p[k]); + free (p); + MYwrite_char (kidmum[1], (unsigned char) i); + if (i) + MYwrite_word (kidmum[1], y); /* number of bytes sent without error */ + break; + + case RDP_Write: + /* Write Memory Address */ + MYread_word (mumkid[0], &x); /* address */ + MYread_word (mumkid[0], &y); /* nbytes */ + p = (char *) malloc (y); + for (k = 0; k < y; k++) + MYread_char (mumkid[0], &p[k]); + i = armul_rdi.write (p, x, (unsigned *) &y); + free (p); + MYwrite_char (kidmum[1], RDP_Return); + MYwrite_char (kidmum[1], (unsigned char) i); + if (i) + MYwrite_word (kidmum[1], y); /* number of bytes sent without error */ + break; + + case RDP_OSOpReply: + /* OS Operation Reply */ + MYread_char (mumkid[0], &c); + if (c == 1) + MYread_char (mumkid[0], (char *) reply); + if (c == 2) + MYread_word (mumkid[0], reply); + return c; + break; + + default: + fprintf (stderr, + "HELP! Unaccounted-for message during OS request. \n"); + MYwrite_char (kidmum[1], RDP_Fatal); + } + } +}
kid.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: README =================================================================== --- README (nonexistent) +++ README (revision 816) @@ -0,0 +1,27 @@ + +This directory contains the standard release of the ARMulator from +Advanced RISC Machines, and was ftp'd from. + +ftp.cl.cam.ac.uk:/arm/gnu + +It likes to use TCP/IP between the simulator and the host, which is +nice, but is a pain to use under anything non-unix. + +I've added created a new Makefile.in (the original in Makefile.orig) +to build a version of the simulator without the TCP/IP stuff, and a +wrapper.c to link directly into gdb and the run command. + +It should be possible (barring major changes in the layout of +the armulator) to upgrade the simulator by copying all the files +out of a release into this directory and renaming the Makefile. + +(Except that I changed armos.c to work more simply with our +simulator rigs) + +Steve + +sac@cygnus.com + +Mon May 15 12:03:28 PDT 1995 + +
README 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: wrapper.c =================================================================== --- wrapper.c (nonexistent) +++ wrapper.c (revision 816) @@ -0,0 +1,942 @@ +/* run front end support for arm + Copyright (C) 1995, 1996, 1997, 2000, 2001, 2002, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. + + This file is part of ARM SIM. + + 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 file provides the interface between the simulator and + run.c and gdb (when the simulator is linked with gdb). + All simulator interaction should go through this file. */ + +#include +#include +#include +#include +#include +#include "gdb/callback.h" +#include "gdb/remote-sim.h" +#include "armdefs.h" +#include "armemu.h" +#include "dbg_rdi.h" +#include "ansidecl.h" +#include "sim-utils.h" +#include "run-sim.h" +#include "gdb/sim-arm.h" +#include "gdb/signals.h" + +host_callback *sim_callback; + +static struct ARMul_State *state; + +/* Who is using the simulator. */ +static SIM_OPEN_KIND sim_kind; + +/* argv[0] */ +static char *myname; + +/* Memory size in bytes. */ +static int mem_size = (1 << 21); + +/* Non-zero to display start up banner, and maybe other things. */ +static int verbosity; + +/* Non-zero to set big endian mode. */ +static int big_endian; + +int stop_simulator; + +/* Cirrus DSP registers. + + We need to define these registers outside of maverick.c because + maverick.c might not be linked in unless --target=arm9e-* in which + case wrapper.c will not compile because it tries to access Cirrus + registers. This should all go away once we get the Cirrus and ARM + Coprocessor to coexist in armcopro.c-- aldyh. */ + +struct maverick_regs +{ + union + { + int i; + float f; + } upper; + + union + { + int i; + float f; + } lower; +}; + +union maverick_acc_regs +{ + long double ld; /* Acc registers are 72-bits. */ +}; + +struct maverick_regs DSPregs[16]; +union maverick_acc_regs DSPacc[4]; +ARMword DSPsc; + +static void +init () +{ + static int done; + + if (!done) + { + ARMul_EmulateInit (); + state = ARMul_NewState (); + state->bigendSig = (big_endian ? HIGH : LOW); + ARMul_MemoryInit (state, mem_size); + ARMul_OSInit (state); + state->verbose = verbosity; + done = 1; + } +} + +/* Set verbosity level of simulator. + This is not intended to produce detailed tracing or debugging information. + Just summaries. */ +/* FIXME: common/run.c doesn't do this yet. */ + +void +sim_set_verbose (v) + int v; +{ + verbosity = v; +} + +/* Set the memory size to SIZE bytes. + Must be called before initializing simulator. */ +/* FIXME: Rename to sim_set_mem_size. */ + +void +sim_size (size) + int size; +{ + mem_size = size; +} + +void +ARMul_ConsolePrint VPARAMS ((ARMul_State * state, + const char * format, + ...)) +{ + va_list ap; + + if (state->verbose) + { + va_start (ap, format); + vprintf (format, ap); + va_end (ap); + } +} + +ARMword +ARMul_Debug (state, pc, instr) + ARMul_State * state ATTRIBUTE_UNUSED; + ARMword pc ATTRIBUTE_UNUSED; + ARMword instr ATTRIBUTE_UNUSED; +{ + return 0; +} + +int +sim_write (sd, addr, buffer, size) + SIM_DESC sd ATTRIBUTE_UNUSED; + SIM_ADDR addr; + unsigned char * buffer; + int size; +{ + int i; + + init (); + + for (i = 0; i < size; i++) + ARMul_SafeWriteByte (state, addr + i, buffer[i]); + + return size; +} + +int +sim_read (sd, addr, buffer, size) + SIM_DESC sd ATTRIBUTE_UNUSED; + SIM_ADDR addr; + unsigned char * buffer; + int size; +{ + int i; + + init (); + + for (i = 0; i < size; i++) + buffer[i] = ARMul_SafeReadByte (state, addr + i); + + return size; +} + +int +sim_trace (sd) + SIM_DESC sd ATTRIBUTE_UNUSED; +{ + (*sim_callback->printf_filtered) + (sim_callback, + "This simulator does not support tracing\n"); + return 1; +} + +int +sim_stop (sd) + SIM_DESC sd ATTRIBUTE_UNUSED; +{ + state->Emulate = STOP; + stop_simulator = 1; + return 1; +} + +void +sim_resume (sd, step, siggnal) + SIM_DESC sd ATTRIBUTE_UNUSED; + int step; + int siggnal ATTRIBUTE_UNUSED; +{ + state->EndCondition = 0; + stop_simulator = 0; + + if (step) + { + state->Reg[15] = ARMul_DoInstr (state); + if (state->EndCondition == 0) + state->EndCondition = RDIError_BreakpointReached; + } + else + { + state->NextInstr = RESUME; /* treat as PC change */ + state->Reg[15] = ARMul_DoProg (state); + } + + FLUSHPIPE; +} + +SIM_RC +sim_create_inferior (sd, abfd, argv, env) + SIM_DESC sd ATTRIBUTE_UNUSED; + struct bfd * abfd; + char ** argv; + char ** env; +{ + int argvlen = 0; + int mach; + char **arg; + + if (abfd != NULL) + ARMul_SetPC (state, bfd_get_start_address (abfd)); + else + ARMul_SetPC (state, 0); /* ??? */ + + mach = bfd_get_mach (abfd); + + switch (mach) + { + default: + (*sim_callback->printf_filtered) + (sim_callback, + "Unknown machine type '%d'; please update sim_create_inferior.\n", + mach); + /* fall through */ + + case 0: + /* We wouldn't set the machine type with earlier toolchains, so we + explicitly select a processor capable of supporting all ARMs in + 32bit mode. */ + /* We choose the XScale rather than the iWMMXt, because the iWMMXt + removes the FPE emulator, since it conflicts with its coprocessors. + For the most generic ARM support, we want the FPE emulator in place. */ + case bfd_mach_arm_XScale: + ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop); + break; + + case bfd_mach_arm_iWMMXt: + { + extern int SWI_vector_installed; + ARMword i; + + if (! SWI_vector_installed) + { + /* Intialise the hardware vectors to zero. */ + if (! SWI_vector_installed) + for (i = ARMul_ResetV; i <= ARMFIQV; i += 4) + ARMul_WriteWord (state, i, 0); + + /* ARM_WriteWord will have detected the write to the SWI vector, + but we want SWI_vector_installed to remain at 0 so that thumb + mode breakpoints will work. */ + SWI_vector_installed = 0; + } + } + ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_iWMMXt_Prop); + break; + + case bfd_mach_arm_ep9312: + ARMul_SelectProcessor (state, ARM_v4_Prop | ARM_ep9312_Prop); + break; + + case bfd_mach_arm_5: + if (bfd_family_coff (abfd)) + { + /* This is a special case in order to support COFF based ARM toolchains. + The COFF header does not have enough room to store all the different + kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default + to v5. (See coff_set_flags() in bdf/coffcode.h). So if we see a v5 + machine type here, we assume it could be any of the above architectures + and so select the most feature-full. */ + ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop); + break; + } + /* Otherwise drop through. */ + + case bfd_mach_arm_5T: + ARMul_SelectProcessor (state, ARM_v5_Prop); + break; + + case bfd_mach_arm_5TE: + ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop); + break; + + case bfd_mach_arm_4: + case bfd_mach_arm_4T: + ARMul_SelectProcessor (state, ARM_v4_Prop); + break; + + case bfd_mach_arm_3: + case bfd_mach_arm_3M: + ARMul_SelectProcessor (state, ARM_Lock_Prop); + break; + + case bfd_mach_arm_2: + case bfd_mach_arm_2a: + ARMul_SelectProcessor (state, ARM_Fix26_Prop); + break; + } + + if ( mach != bfd_mach_arm_3 + && mach != bfd_mach_arm_3M + && mach != bfd_mach_arm_2 + && mach != bfd_mach_arm_2a) + { + /* Reset mode to ARM. A gdb user may rerun a program that had entered + THUMB mode from the start and cause the ARM-mode startup code to be + executed in THUMB mode. */ + ARMul_SetCPSR (state, SVC32MODE); + } + + if (argv != NULL) + { + /* Set up the command line by laboriously stringing together + the environment carefully picked apart by our caller. */ + + /* Free any old stuff. */ + if (state->CommandLine != NULL) + { + free (state->CommandLine); + state->CommandLine = NULL; + } + + /* See how much we need. */ + for (arg = argv; *arg != NULL; arg++) + argvlen += strlen (*arg) + 1; + + /* Allocate it. */ + state->CommandLine = malloc (argvlen + 1); + if (state->CommandLine != NULL) + { + arg = argv; + state->CommandLine[0] = '\0'; + + for (arg = argv; *arg != NULL; arg++) + { + strcat (state->CommandLine, *arg); + strcat (state->CommandLine, " "); + } + } + } + + if (env != NULL) + { + /* Now see if there's a MEMSIZE spec in the environment. */ + while (*env) + { + if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0) + { + char *end_of_num; + + /* Set up memory limit. */ + state->MemSize = + strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0); + } + env++; + } + } + + return SIM_RC_OK; +} + +void +sim_info (sd, verbose) + SIM_DESC sd ATTRIBUTE_UNUSED; + int verbose ATTRIBUTE_UNUSED; +{ +} + +static int +frommem (state, memory) + struct ARMul_State *state; + unsigned char *memory; +{ + if (state->bigendSig == HIGH) + return (memory[0] << 24) | (memory[1] << 16) + | (memory[2] << 8) | (memory[3] << 0); + else + return (memory[3] << 24) | (memory[2] << 16) + | (memory[1] << 8) | (memory[0] << 0); +} + +static void +tomem (state, memory, val) + struct ARMul_State *state; + unsigned char *memory; + int val; +{ + if (state->bigendSig == HIGH) + { + memory[0] = val >> 24; + memory[1] = val >> 16; + memory[2] = val >> 8; + memory[3] = val >> 0; + } + else + { + memory[3] = val >> 24; + memory[2] = val >> 16; + memory[1] = val >> 8; + memory[0] = val >> 0; + } +} + +int +sim_store_register (sd, rn, memory, length) + SIM_DESC sd ATTRIBUTE_UNUSED; + int rn; + unsigned char *memory; + int length ATTRIBUTE_UNUSED; +{ + init (); + + switch ((enum sim_arm_regs) rn) + { + case SIM_ARM_R0_REGNUM: + case SIM_ARM_R1_REGNUM: + case SIM_ARM_R2_REGNUM: + case SIM_ARM_R3_REGNUM: + case SIM_ARM_R4_REGNUM: + case SIM_ARM_R5_REGNUM: + case SIM_ARM_R6_REGNUM: + case SIM_ARM_R7_REGNUM: + case SIM_ARM_R8_REGNUM: + case SIM_ARM_R9_REGNUM: + case SIM_ARM_R10_REGNUM: + case SIM_ARM_R11_REGNUM: + case SIM_ARM_R12_REGNUM: + case SIM_ARM_R13_REGNUM: + case SIM_ARM_R14_REGNUM: + case SIM_ARM_R15_REGNUM: /* PC */ + case SIM_ARM_FP0_REGNUM: + case SIM_ARM_FP1_REGNUM: + case SIM_ARM_FP2_REGNUM: + case SIM_ARM_FP3_REGNUM: + case SIM_ARM_FP4_REGNUM: + case SIM_ARM_FP5_REGNUM: + case SIM_ARM_FP6_REGNUM: + case SIM_ARM_FP7_REGNUM: + case SIM_ARM_FPS_REGNUM: + ARMul_SetReg (state, state->Mode, rn, frommem (state, memory)); + break; + + case SIM_ARM_PS_REGNUM: + state->Cpsr = frommem (state, memory); + ARMul_CPSRAltered (state); + break; + + case SIM_ARM_MAVERIC_COP0R0_REGNUM: + case SIM_ARM_MAVERIC_COP0R1_REGNUM: + case SIM_ARM_MAVERIC_COP0R2_REGNUM: + case SIM_ARM_MAVERIC_COP0R3_REGNUM: + case SIM_ARM_MAVERIC_COP0R4_REGNUM: + case SIM_ARM_MAVERIC_COP0R5_REGNUM: + case SIM_ARM_MAVERIC_COP0R6_REGNUM: + case SIM_ARM_MAVERIC_COP0R7_REGNUM: + case SIM_ARM_MAVERIC_COP0R8_REGNUM: + case SIM_ARM_MAVERIC_COP0R9_REGNUM: + case SIM_ARM_MAVERIC_COP0R10_REGNUM: + case SIM_ARM_MAVERIC_COP0R11_REGNUM: + case SIM_ARM_MAVERIC_COP0R12_REGNUM: + case SIM_ARM_MAVERIC_COP0R13_REGNUM: + case SIM_ARM_MAVERIC_COP0R14_REGNUM: + case SIM_ARM_MAVERIC_COP0R15_REGNUM: + memcpy (& DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM], + memory, sizeof (struct maverick_regs)); + return sizeof (struct maverick_regs); + + case SIM_ARM_MAVERIC_DSPSC_REGNUM: + memcpy (&DSPsc, memory, sizeof DSPsc); + return sizeof DSPsc; + + case SIM_ARM_IWMMXT_COP0R0_REGNUM: + case SIM_ARM_IWMMXT_COP0R1_REGNUM: + case SIM_ARM_IWMMXT_COP0R2_REGNUM: + case SIM_ARM_IWMMXT_COP0R3_REGNUM: + case SIM_ARM_IWMMXT_COP0R4_REGNUM: + case SIM_ARM_IWMMXT_COP0R5_REGNUM: + case SIM_ARM_IWMMXT_COP0R6_REGNUM: + case SIM_ARM_IWMMXT_COP0R7_REGNUM: + case SIM_ARM_IWMMXT_COP0R8_REGNUM: + case SIM_ARM_IWMMXT_COP0R9_REGNUM: + case SIM_ARM_IWMMXT_COP0R10_REGNUM: + case SIM_ARM_IWMMXT_COP0R11_REGNUM: + case SIM_ARM_IWMMXT_COP0R12_REGNUM: + case SIM_ARM_IWMMXT_COP0R13_REGNUM: + case SIM_ARM_IWMMXT_COP0R14_REGNUM: + case SIM_ARM_IWMMXT_COP0R15_REGNUM: + case SIM_ARM_IWMMXT_COP1R0_REGNUM: + case SIM_ARM_IWMMXT_COP1R1_REGNUM: + case SIM_ARM_IWMMXT_COP1R2_REGNUM: + case SIM_ARM_IWMMXT_COP1R3_REGNUM: + case SIM_ARM_IWMMXT_COP1R4_REGNUM: + case SIM_ARM_IWMMXT_COP1R5_REGNUM: + case SIM_ARM_IWMMXT_COP1R6_REGNUM: + case SIM_ARM_IWMMXT_COP1R7_REGNUM: + case SIM_ARM_IWMMXT_COP1R8_REGNUM: + case SIM_ARM_IWMMXT_COP1R9_REGNUM: + case SIM_ARM_IWMMXT_COP1R10_REGNUM: + case SIM_ARM_IWMMXT_COP1R11_REGNUM: + case SIM_ARM_IWMMXT_COP1R12_REGNUM: + case SIM_ARM_IWMMXT_COP1R13_REGNUM: + case SIM_ARM_IWMMXT_COP1R14_REGNUM: + case SIM_ARM_IWMMXT_COP1R15_REGNUM: + return Store_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory); + + default: + return 0; + } + + return -1; +} + +int +sim_fetch_register (sd, rn, memory, length) + SIM_DESC sd ATTRIBUTE_UNUSED; + int rn; + unsigned char *memory; + int length ATTRIBUTE_UNUSED; +{ + ARMword regval; + + init (); + + switch ((enum sim_arm_regs) rn) + { + case SIM_ARM_R0_REGNUM: + case SIM_ARM_R1_REGNUM: + case SIM_ARM_R2_REGNUM: + case SIM_ARM_R3_REGNUM: + case SIM_ARM_R4_REGNUM: + case SIM_ARM_R5_REGNUM: + case SIM_ARM_R6_REGNUM: + case SIM_ARM_R7_REGNUM: + case SIM_ARM_R8_REGNUM: + case SIM_ARM_R9_REGNUM: + case SIM_ARM_R10_REGNUM: + case SIM_ARM_R11_REGNUM: + case SIM_ARM_R12_REGNUM: + case SIM_ARM_R13_REGNUM: + case SIM_ARM_R14_REGNUM: + case SIM_ARM_R15_REGNUM: /* PC */ + regval = ARMul_GetReg (state, state->Mode, rn); + break; + + case SIM_ARM_FP0_REGNUM: + case SIM_ARM_FP1_REGNUM: + case SIM_ARM_FP2_REGNUM: + case SIM_ARM_FP3_REGNUM: + case SIM_ARM_FP4_REGNUM: + case SIM_ARM_FP5_REGNUM: + case SIM_ARM_FP6_REGNUM: + case SIM_ARM_FP7_REGNUM: + case SIM_ARM_FPS_REGNUM: + memset (memory, 0, length); + return 0; + + case SIM_ARM_PS_REGNUM: + regval = ARMul_GetCPSR (state); + break; + + case SIM_ARM_MAVERIC_COP0R0_REGNUM: + case SIM_ARM_MAVERIC_COP0R1_REGNUM: + case SIM_ARM_MAVERIC_COP0R2_REGNUM: + case SIM_ARM_MAVERIC_COP0R3_REGNUM: + case SIM_ARM_MAVERIC_COP0R4_REGNUM: + case SIM_ARM_MAVERIC_COP0R5_REGNUM: + case SIM_ARM_MAVERIC_COP0R6_REGNUM: + case SIM_ARM_MAVERIC_COP0R7_REGNUM: + case SIM_ARM_MAVERIC_COP0R8_REGNUM: + case SIM_ARM_MAVERIC_COP0R9_REGNUM: + case SIM_ARM_MAVERIC_COP0R10_REGNUM: + case SIM_ARM_MAVERIC_COP0R11_REGNUM: + case SIM_ARM_MAVERIC_COP0R12_REGNUM: + case SIM_ARM_MAVERIC_COP0R13_REGNUM: + case SIM_ARM_MAVERIC_COP0R14_REGNUM: + case SIM_ARM_MAVERIC_COP0R15_REGNUM: + memcpy (memory, & DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM], + sizeof (struct maverick_regs)); + return sizeof (struct maverick_regs); + + case SIM_ARM_MAVERIC_DSPSC_REGNUM: + memcpy (memory, & DSPsc, sizeof DSPsc); + return sizeof DSPsc; + + case SIM_ARM_IWMMXT_COP0R0_REGNUM: + case SIM_ARM_IWMMXT_COP0R1_REGNUM: + case SIM_ARM_IWMMXT_COP0R2_REGNUM: + case SIM_ARM_IWMMXT_COP0R3_REGNUM: + case SIM_ARM_IWMMXT_COP0R4_REGNUM: + case SIM_ARM_IWMMXT_COP0R5_REGNUM: + case SIM_ARM_IWMMXT_COP0R6_REGNUM: + case SIM_ARM_IWMMXT_COP0R7_REGNUM: + case SIM_ARM_IWMMXT_COP0R8_REGNUM: + case SIM_ARM_IWMMXT_COP0R9_REGNUM: + case SIM_ARM_IWMMXT_COP0R10_REGNUM: + case SIM_ARM_IWMMXT_COP0R11_REGNUM: + case SIM_ARM_IWMMXT_COP0R12_REGNUM: + case SIM_ARM_IWMMXT_COP0R13_REGNUM: + case SIM_ARM_IWMMXT_COP0R14_REGNUM: + case SIM_ARM_IWMMXT_COP0R15_REGNUM: + case SIM_ARM_IWMMXT_COP1R0_REGNUM: + case SIM_ARM_IWMMXT_COP1R1_REGNUM: + case SIM_ARM_IWMMXT_COP1R2_REGNUM: + case SIM_ARM_IWMMXT_COP1R3_REGNUM: + case SIM_ARM_IWMMXT_COP1R4_REGNUM: + case SIM_ARM_IWMMXT_COP1R5_REGNUM: + case SIM_ARM_IWMMXT_COP1R6_REGNUM: + case SIM_ARM_IWMMXT_COP1R7_REGNUM: + case SIM_ARM_IWMMXT_COP1R8_REGNUM: + case SIM_ARM_IWMMXT_COP1R9_REGNUM: + case SIM_ARM_IWMMXT_COP1R10_REGNUM: + case SIM_ARM_IWMMXT_COP1R11_REGNUM: + case SIM_ARM_IWMMXT_COP1R12_REGNUM: + case SIM_ARM_IWMMXT_COP1R13_REGNUM: + case SIM_ARM_IWMMXT_COP1R14_REGNUM: + case SIM_ARM_IWMMXT_COP1R15_REGNUM: + return Fetch_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory); + + default: + return 0; + } + + while (length) + { + tomem (state, memory, regval); + + length -= 4; + memory += 4; + regval = 0; + } + + return -1; +} + +#ifdef SIM_TARGET_SWITCHES + +static void sim_target_parse_arg_array PARAMS ((char **)); + +typedef struct +{ + char * swi_option; + unsigned int swi_mask; +} swi_options; + +#define SWI_SWITCH "--swi-support" + +static swi_options options[] = + { + { "none", 0 }, + { "demon", SWI_MASK_DEMON }, + { "angel", SWI_MASK_ANGEL }, + { "redboot", SWI_MASK_REDBOOT }, + { "all", -1 }, + { "NONE", 0 }, + { "DEMON", SWI_MASK_DEMON }, + { "ANGEL", SWI_MASK_ANGEL }, + { "REDBOOT", SWI_MASK_REDBOOT }, + { "ALL", -1 } + }; + + +int +sim_target_parse_command_line (argc, argv) + int argc; + char ** argv; +{ + int i; + + for (i = 1; i < argc; i++) + { + char * ptr = argv[i]; + int arg; + + if ((ptr == NULL) || (* ptr != '-')) + break; + + if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0) + continue; + + if (ptr[sizeof SWI_SWITCH - 1] == 0) + { + /* Remove this option from the argv array. */ + for (arg = i; arg < argc; arg ++) + argv[arg] = argv[arg + 1]; + argc --; + + ptr = argv[i]; + } + else + ptr += sizeof SWI_SWITCH; + + swi_mask = 0; + + while (* ptr) + { + int i; + + for (i = sizeof options / sizeof options[0]; i--;) + if (strncmp (ptr, options[i].swi_option, + strlen (options[i].swi_option)) == 0) + { + swi_mask |= options[i].swi_mask; + ptr += strlen (options[i].swi_option); + + if (* ptr == ',') + ++ ptr; + + break; + } + + if (i < 0) + break; + } + + if (* ptr != 0) + fprintf (stderr, "Ignoring swi options: %s\n", ptr); + + /* Remove this option from the argv array. */ + for (arg = i; arg < argc; arg ++) + argv[arg] = argv[arg + 1]; + argc --; + i --; + } + return argc; +} + +static void +sim_target_parse_arg_array (argv) + char ** argv; +{ + int i; + + for (i = 0; argv[i]; i++) + ; + + sim_target_parse_command_line (i, argv); +} + +void +sim_target_display_usage (help) + int help; +{ + FILE *stream = help ? stdout : stderr; + + fprintf (stream, "%s= Comma seperated list of SWI protocols to supoport.\n\ + This list can contain: NONE, DEMON, ANGEL, REDBOOT and/or ALL.\n", + SWI_SWITCH); +} +#endif + +SIM_DESC +sim_open (kind, ptr, abfd, argv) + SIM_OPEN_KIND kind; + host_callback *ptr; + struct bfd *abfd; + char **argv; +{ + sim_kind = kind; + if (myname) free (myname); + myname = (char *) xstrdup (argv[0]); + sim_callback = ptr; + +#ifdef SIM_TARGET_SWITCHES + sim_target_parse_arg_array (argv); +#endif + + /* Decide upon the endian-ness of the processor. + If we can, get the information from the bfd itself. + Otherwise look to see if we have been given a command + line switch that tells us. Otherwise default to little endian. */ + if (abfd != NULL) + big_endian = bfd_big_endian (abfd); + else if (argv[1] != NULL) + { + int i; + + /* Scan for endian-ness and memory-size switches. */ + for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++) + if (argv[i][0] == '-' && argv[i][1] == 'E') + { + char c; + + if ((c = argv[i][2]) == 0) + { + ++i; + c = argv[i][0]; + } + + switch (c) + { + case 0: + sim_callback->printf_filtered + (sim_callback, "No argument to -E option provided\n"); + break; + + case 'b': + case 'B': + big_endian = 1; + break; + + case 'l': + case 'L': + big_endian = 0; + break; + + default: + sim_callback->printf_filtered + (sim_callback, "Unrecognised argument to -E option\n"); + break; + } + } + else if (argv[i][0] == '-' && argv[i][1] == 'm') + { + if (argv[i][2] != '\0') + sim_size (atoi (&argv[i][2])); + else if (argv[i + 1] != NULL) + { + sim_size (atoi (argv[i + 1])); + i++; + } + else + { + sim_callback->printf_filtered (sim_callback, + "Missing argument to -m option\n"); + return NULL; + } + + } + } + + return (SIM_DESC) 1; +} + +void +sim_close (sd, quitting) + SIM_DESC sd ATTRIBUTE_UNUSED; + int quitting ATTRIBUTE_UNUSED; +{ + if (myname) + free (myname); + myname = NULL; +} + +SIM_RC +sim_load (sd, prog, abfd, from_tty) + SIM_DESC sd; + char *prog; + bfd *abfd; + int from_tty ATTRIBUTE_UNUSED; +{ + bfd *prog_bfd; + + prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd, + sim_kind == SIM_OPEN_DEBUG, 0, sim_write); + if (prog_bfd == NULL) + return SIM_RC_FAIL; + ARMul_SetPC (state, bfd_get_start_address (prog_bfd)); + if (abfd == NULL) + bfd_close (prog_bfd); + return SIM_RC_OK; +} + +void +sim_stop_reason (sd, reason, sigrc) + SIM_DESC sd ATTRIBUTE_UNUSED; + enum sim_stop *reason; + int *sigrc; +{ + if (stop_simulator) + { + *reason = sim_stopped; + *sigrc = TARGET_SIGNAL_INT; + } + else if (state->EndCondition == 0) + { + *reason = sim_exited; + *sigrc = state->Reg[0] & 255; + } + else + { + *reason = sim_stopped; + if (state->EndCondition == RDIError_BreakpointReached) + *sigrc = TARGET_SIGNAL_TRAP; + else if ( state->EndCondition == RDIError_DataAbort + || state->EndCondition == RDIError_AddressException) + *sigrc = TARGET_SIGNAL_BUS; + else + *sigrc = 0; + } +} + +void +sim_do_command (sd, cmd) + SIM_DESC sd ATTRIBUTE_UNUSED; + char *cmd ATTRIBUTE_UNUSED; +{ + (*sim_callback->printf_filtered) + (sim_callback, + "This simulator does not accept any commands.\n"); +} + +void +sim_set_callbacks (ptr) + host_callback *ptr; +{ + sim_callback = ptr; +}
wrapper.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: dbg_cp.h =================================================================== --- dbg_cp.h (nonexistent) +++ dbg_cp.h (revision 816) @@ -0,0 +1,70 @@ +/* dbg_cp.h -- ARMulator debug interface: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef Dbg_CP__h + +#define Dbg_CP__h + +#define Dbg_Access_Readable 1 +#define Dbg_Access_Writable 2 +#define Dbg_Access_CPDT 4 /* else CPRT */ + +typedef struct +{ + unsigned short rmin, rmax; + /* a single description can be used for a range of registers with + the same properties *accessed via CPDT instructions* + */ + unsigned char nbytes; /* size of register */ + unsigned char access; /* see above (Access_xxx) */ + union + { + struct + { + /* CPDT instructions do not allow the coprocessor much freedom: + only bit 22 ('N') and 12-15 ('CRd') are free for the + coprocessor to use as it sees fit. */ + unsigned char nbit; + unsigned char rdbits; + } + cpdt; + struct + { + /* CPRT instructions have much more latitude. The bits fixed + by the ARM are 24..31 (condition mask & opcode) + 20 (direction) + 8..15 (cpnum, arm register) + 4 (CPRT not CPDO) + leaving 14 bits free to the coprocessor (fortunately + falling within two bytes). */ + unsigned char read_b0, read_b1, write_b0, write_b1; + } + cprt; + } + accessinst; +} +Dbg_CoProRegDesc; + +struct Dbg_CoProDesc +{ + int entries; + Dbg_CoProRegDesc regdesc[1 /* really nentries */ ]; +}; + +#define Dbg_CoProDesc_Size(n) (sizeof(struct Dbg_CoProDesc) + (n-1)*sizeof(Dbg_CoProRegDesc)) + +#endif
dbg_cp.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: main.c =================================================================== --- main.c (nonexistent) +++ main.c (revision 816) @@ -0,0 +1,194 @@ +/* main.c -- top level of ARMulator: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/**********************************************************************/ +/* Forks the ARMulator and hangs on a socket passing on RDP messages */ +/* down a pipe to the ARMulator which translates them into RDI calls. */ +/**********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "armdefs.h" +#include "dbg_rdi.h" +#include "dbg_conf.h" + +#define MAXHOSTNAMELENGTH 64 + +/* Read and write routines down sockets and pipes */ + +void MYread_chars (int sock, void *p, int n); +unsigned char MYread_char (int sock); +ARMword MYread_word (int sock); +void MYread_FPword (int sock, char *putinhere); + +void MYwrite_word (int sock, ARMword i); +void MYwrite_string (int sock, char *s); +void MYwrite_FPword (int sock, char *fromhere); +void MYwrite_char (int sock, unsigned char c); + +void passon (int source, int dest, int n); + + +/* Mother and child processes */ +void parent (void); +void kid (void); + +/* The child process id. */ +pid_t child; + +/* The socket to the debugger */ +int debugsock; + +/* The pipes between the two processes */ +int mumkid[2]; +int kidmum[2]; + +/* A pipe for handling SWI return values that goes straight from the */ +/* parent to the ARMulator host interface, bypassing the childs RDP */ +/* to RDI interpreter */ +int DebuggerARMul[2]; + +/* The maximum number of file descriptors */ +int nfds; + +/* The socket handle */ +int sockethandle; + +/* The machine name */ +char localhost[MAXHOSTNAMELENGTH + 1]; + +/* The socket number */ +unsigned int socketnumber; + +/**************************************************************/ +/* Takes one argument: the socket number. */ +/* Opens a socket to the debugger, and once opened spawns the */ +/* ARMulator and sets up a couple of pipes. */ +/**************************************************************/ +int +main (int argc, char *argv[]) +{ + int i; + struct sockaddr_in devil, isa; + struct hostent *hp; + + + if (argc == 1) + { + fprintf (stderr, "No socket number\n"); + return 1; + } + + sscanf (argv[1], "%d", &socketnumber); + if (!socketnumber || socketnumber > 0xffff) + { + fprintf (stderr, "Invalid socket number: %d\n", socketnumber); + return 1; + } + + gethostname (localhost, MAXHOSTNAMELENGTH); + hp = gethostbyname (localhost); + if (!hp) + { + fprintf (stderr, "Cannot get local host info\n"); + return 1; + } + + /* Open a socket */ + sockethandle = socket (hp->h_addrtype, SOCK_STREAM, 0); + if (sockethandle < 0) + { + perror ("socket"); + return 1; + } + + devil.sin_family = hp->h_addrtype; + devil.sin_port = htons (socketnumber); + devil.sin_addr.s_addr = 0; + for (i = 0; i < sizeof (devil.sin_zero); i++) + devil.sin_zero[i] = '\000'; + memcpy (&devil.sin_addr, hp->h_addr_list[0], hp->h_length); + + if (bind (sockethandle, &devil, sizeof (devil)) < 0) + { + perror ("bind"); + return 1; + } + + /* May only accept one debugger at once */ + + if (listen (sockethandle, 0)) + { + perror ("listen"); + return 1; + } + + fprintf (stderr, "Waiting for connection from debugger..."); + + debugsock = accept (sockethandle, &isa, &i); + if (debugsock < 0) + { + perror ("accept"); + return 1; + } + + fprintf (stderr, " done.\nConnection Established.\n"); + + nfds = getdtablesize (); + + if (pipe (mumkid)) + { + perror ("pipe"); + return 1; + } + if (pipe (kidmum)) + { + perror ("pipe"); + return 1; + } + + if (pipe (DebuggerARMul)) + { + perror ("pipe"); + return 1; + } + +#ifdef DEBUG + fprintf (stderr, "Created pipes ok\n"); +#endif + + child = fork (); + +#ifdef DEBUG + fprintf (stderr, "fork() ok\n"); +#endif + + if (child == 0) + kid (); + if (child != -1) + parent (); + + perror ("fork"); + return 1; +}
main.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: iwmmxt.c =================================================================== --- iwmmxt.c (nonexistent) +++ iwmmxt.c (revision 816) @@ -0,0 +1,3731 @@ +/* iwmmxt.c -- Intel(r) Wireless MMX(tm) technology co-processor interface. + Copyright (C) 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + Contributed by matthew green (mrg@redhat.com). + + 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 "armdefs.h" +#include "armos.h" +#include "armemu.h" +#include "ansidecl.h" +#include "iwmmxt.h" + +/* #define DEBUG 1 */ + +/* Intel(r) Wireless MMX(tm) technology co-processor. + It uses co-processor numbers (0 and 1). There are 16 vector registers wRx + and 16 control registers wCx. Co-processors 0 and 1 are used in MCR/MRC + to access wRx and wCx respectively. */ + +static ARMdword wR[16]; +static ARMword wC[16] = { 0x69051010 }; + +#define SUBSTR(w,t,m,n) ((t)(w << ((sizeof (t) * 8 - 1) - (n))) \ + >> (((sizeof (t) * 8 - 1) - (n)) + (m))) +#define wCBITS(w,x,y) SUBSTR (wC[w], ARMword, x, y) +#define wRBITS(w,x,y) SUBSTR (wR[w], ARMdword, x, y) +#define wCID 0 +#define wCon 1 +#define wCSSF 2 +#define wCASF 3 +#define wCGR0 8 +#define wCGR1 9 +#define wCGR2 10 +#define wCGR3 11 + +/* Bits in the wCon register. */ +#define WCON_CUP (1 << 0) +#define WCON_MUP (1 << 1) + +/* Set the SIMD wCASF flags for 8, 16, 32 or 64-bit operations. */ +#define SIMD8_SET(x, v, n, b) (x) |= ((v != 0) << ((((b) + 1) * 4) + (n))) +#define SIMD16_SET(x, v, n, h) (x) |= ((v != 0) << ((((h) + 1) * 8) + (n))) +#define SIMD32_SET(x, v, n, w) (x) |= ((v != 0) << ((((w) + 1) * 16) + (n))) +#define SIMD64_SET(x, v, n) (x) |= ((v != 0) << (32 + (n))) + +/* Flags to pass as "n" above. */ +#define SIMD_NBIT -1 +#define SIMD_ZBIT -2 +#define SIMD_CBIT -3 +#define SIMD_VBIT -4 + +/* Various status bit macros. */ +#define NBIT8(x) ((x) & 0x80) +#define NBIT16(x) ((x) & 0x8000) +#define NBIT32(x) ((x) & 0x80000000) +#define NBIT64(x) ((x) & 0x8000000000000000ULL) +#define ZBIT8(x) (((x) & 0xff) == 0) +#define ZBIT16(x) (((x) & 0xffff) == 0) +#define ZBIT32(x) (((x) & 0xffffffff) == 0) +#define ZBIT64(x) (x == 0) + +/* Access byte/half/word "n" of register "x". */ +#define wRBYTE(x,n) wRBITS ((x), (n) * 8, (n) * 8 + 7) +#define wRHALF(x,n) wRBITS ((x), (n) * 16, (n) * 16 + 15) +#define wRWORD(x,n) wRBITS ((x), (n) * 32, (n) * 32 + 31) + +/* Macro to handle how the G bit selects wCGR registers. */ +#define DECODE_G_BIT(state, instr, shift) \ +{ \ + unsigned int reg; \ + \ + reg = BITS (0, 3); \ + \ + if (BIT (8)) /* G */ \ + { \ + if (reg < wCGR0 || reg > wCGR3) \ + { \ + ARMul_UndefInstr (state, instr); \ + return ARMul_DONE; \ + } \ + shift = wC [reg]; \ + } \ + else \ + shift = wR [reg]; \ + \ + shift &= 0xff; \ +} + +/* Index calculations for the satrv[] array. */ +#define BITIDX8(x) (x) +#define BITIDX16(x) (((x) + 1) * 2 - 1) +#define BITIDX32(x) (((x) + 1) * 4 - 1) + +/* Sign extension macros. */ +#define EXTEND8(a) ((a) & 0x80 ? ((a) | 0xffffff00) : (a)) +#define EXTEND16(a) ((a) & 0x8000 ? ((a) | 0xffff0000) : (a)) +#define EXTEND32(a) ((a) & 0x80000000ULL ? ((a) | 0xffffffff00000000ULL) : (a)) + +/* Set the wCSSF from 8 values. */ +#define SET_wCSSF(a,b,c,d,e,f,g,h) \ + wC[wCSSF] = (((h) != 0) << 7) | (((g) != 0) << 6) \ + | (((f) != 0) << 5) | (((e) != 0) << 4) \ + | (((d) != 0) << 3) | (((c) != 0) << 2) \ + | (((b) != 0) << 1) | (((a) != 0) << 0); + +/* Set the wCSSR from an array with 8 values. */ +#define SET_wCSSFvec(v) \ + SET_wCSSF((v)[0],(v)[1],(v)[2],(v)[3],(v)[4],(v)[5],(v)[6],(v)[7]) + +/* Size qualifiers for vector operations. */ +#define Bqual 0 +#define Hqual 1 +#define Wqual 2 +#define Dqual 3 + +/* Saturation qualifiers for vector operations. */ +#define NoSaturation 0 +#define UnsignedSaturation 1 +#define SignedSaturation 3 + + +/* Prototypes. */ +static ARMword Add32 (ARMword, ARMword, int *, int *, ARMword); +static ARMdword AddS32 (ARMdword, ARMdword, int *, int *); +static ARMdword AddU32 (ARMdword, ARMdword, int *, int *); +static ARMword AddS16 (ARMword, ARMword, int *, int *); +static ARMword AddU16 (ARMword, ARMword, int *, int *); +static ARMword AddS8 (ARMword, ARMword, int *, int *); +static ARMword AddU8 (ARMword, ARMword, int *, int *); +static ARMword Sub32 (ARMword, ARMword, int *, int *, ARMword); +static ARMdword SubS32 (ARMdword, ARMdword, int *, int *); +static ARMdword SubU32 (ARMdword, ARMdword, int *, int *); +static ARMword SubS16 (ARMword, ARMword, int *, int *); +static ARMword SubS8 (ARMword, ARMword, int *, int *); +static ARMword SubU16 (ARMword, ARMword, int *, int *); +static ARMword SubU8 (ARMword, ARMword, int *, int *); +static unsigned char IwmmxtSaturateU8 (signed short, int *); +static signed char IwmmxtSaturateS8 (signed short, int *); +static unsigned short IwmmxtSaturateU16 (signed int, int *); +static signed short IwmmxtSaturateS16 (signed int, int *); +static unsigned long IwmmxtSaturateU32 (signed long long, int *); +static signed long IwmmxtSaturateS32 (signed long long, int *); +static ARMword Compute_Iwmmxt_Address (ARMul_State *, ARMword, int *); +static ARMdword Iwmmxt_Load_Double_Word (ARMul_State *, ARMword); +static ARMword Iwmmxt_Load_Word (ARMul_State *, ARMword); +static ARMword Iwmmxt_Load_Half_Word (ARMul_State *, ARMword); +static ARMword Iwmmxt_Load_Byte (ARMul_State *, ARMword); +static void Iwmmxt_Store_Double_Word (ARMul_State *, ARMword, ARMdword); +static void Iwmmxt_Store_Word (ARMul_State *, ARMword, ARMword); +static void Iwmmxt_Store_Half_Word (ARMul_State *, ARMword, ARMword); +static void Iwmmxt_Store_Byte (ARMul_State *, ARMword, ARMword); +static int Process_Instruction (ARMul_State *, ARMword); + +static int TANDC (ARMul_State *, ARMword); +static int TBCST (ARMul_State *, ARMword); +static int TEXTRC (ARMul_State *, ARMword); +static int TEXTRM (ARMul_State *, ARMword); +static int TINSR (ARMul_State *, ARMword); +static int TMCR (ARMul_State *, ARMword); +static int TMCRR (ARMul_State *, ARMword); +static int TMIA (ARMul_State *, ARMword); +static int TMIAPH (ARMul_State *, ARMword); +static int TMIAxy (ARMul_State *, ARMword); +static int TMOVMSK (ARMul_State *, ARMword); +static int TMRC (ARMul_State *, ARMword); +static int TMRRC (ARMul_State *, ARMword); +static int TORC (ARMul_State *, ARMword); +static int WACC (ARMul_State *, ARMword); +static int WADD (ARMul_State *, ARMword); +static int WALIGNI (ARMword); +static int WALIGNR (ARMul_State *, ARMword); +static int WAND (ARMword); +static int WANDN (ARMword); +static int WAVG2 (ARMword); +static int WCMPEQ (ARMul_State *, ARMword); +static int WCMPGT (ARMul_State *, ARMword); +static int WLDR (ARMul_State *, ARMword); +static int WMAC (ARMword); +static int WMADD (ARMword); +static int WMAX (ARMul_State *, ARMword); +static int WMIN (ARMul_State *, ARMword); +static int WMUL (ARMword); +static int WOR (ARMword); +static int WPACK (ARMul_State *, ARMword); +static int WROR (ARMul_State *, ARMword); +static int WSAD (ARMword); +static int WSHUFH (ARMword); +static int WSLL (ARMul_State *, ARMword); +static int WSRA (ARMul_State *, ARMword); +static int WSRL (ARMul_State *, ARMword); +static int WSTR (ARMul_State *, ARMword); +static int WSUB (ARMul_State *, ARMword); +static int WUNPCKEH (ARMul_State *, ARMword); +static int WUNPCKEL (ARMul_State *, ARMword); +static int WUNPCKIH (ARMul_State *, ARMword); +static int WUNPCKIL (ARMul_State *, ARMword); +static int WXOR (ARMword); + +/* This function does the work of adding two 32bit values + together, and calculating if a carry has occurred. */ + +static ARMword +Add32 (ARMword a1, + ARMword a2, + int * carry_ptr, + int * overflow_ptr, + ARMword sign_mask) +{ + ARMword result = (a1 + a2); + unsigned int uresult = (unsigned int) result; + unsigned int ua1 = (unsigned int) a1; + + /* If (result == a1) and (a2 == 0), + or (result > a2) then we have no carry. */ + * carry_ptr = ((uresult == ua1) ? (a2 != 0) : (uresult < ua1)); + + /* Overflow occurs when both arguments are the + same sign, but the result is a different sign. */ + * overflow_ptr = ( ( (result & sign_mask) && !(a1 & sign_mask) && !(a2 & sign_mask)) + || (!(result & sign_mask) && (a1 & sign_mask) && (a2 & sign_mask))); + + return result; +} + +static ARMdword +AddS32 (ARMdword a1, ARMdword a2, int * carry_ptr, int * overflow_ptr) +{ + ARMdword result; + unsigned int uresult; + unsigned int ua1; + + a1 = EXTEND32 (a1); + a2 = EXTEND32 (a2); + + result = a1 + a2; + uresult = (unsigned int) result; + ua1 = (unsigned int) a1; + + * carry_ptr = ((uresult == a1) ? (a2 != 0) : (uresult < ua1)); + + * overflow_ptr = ( ( (result & 0x80000000ULL) && !(a1 & 0x80000000ULL) && !(a2 & 0x80000000ULL)) + || (!(result & 0x80000000ULL) && (a1 & 0x80000000ULL) && (a2 & 0x80000000ULL))); + + return result; +} + +static ARMdword +AddU32 (ARMdword a1, ARMdword a2, int * carry_ptr, int * overflow_ptr) +{ + ARMdword result; + unsigned int uresult; + unsigned int ua1; + + a1 &= 0xffffffff; + a2 &= 0xffffffff; + + result = a1 + a2; + uresult = (unsigned int) result; + ua1 = (unsigned int) a1; + + * carry_ptr = ((uresult == a1) ? (a2 != 0) : (uresult < ua1)); + + * overflow_ptr = ( ( (result & 0x80000000ULL) && !(a1 & 0x80000000ULL) && !(a2 & 0x80000000ULL)) + || (!(result & 0x80000000ULL) && (a1 & 0x80000000ULL) && (a2 & 0x80000000ULL))); + + return result; +} + +static ARMword +AddS16 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr) +{ + a1 = EXTEND16 (a1); + a2 = EXTEND16 (a2); + + return Add32 (a1, a2, carry_ptr, overflow_ptr, 0x8000); +} + +static ARMword +AddU16 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr) +{ + a1 &= 0xffff; + a2 &= 0xffff; + + return Add32 (a1, a2, carry_ptr, overflow_ptr, 0x8000); +} + +static ARMword +AddS8 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr) +{ + a1 = EXTEND8 (a1); + a2 = EXTEND8 (a2); + + return Add32 (a1, a2, carry_ptr, overflow_ptr, 0x80); +} + +static ARMword +AddU8 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr) +{ + a1 &= 0xff; + a2 &= 0xff; + + return Add32 (a1, a2, carry_ptr, overflow_ptr, 0x80); +} + +static ARMword +Sub32 (ARMword a1, + ARMword a2, + int * borrow_ptr, + int * overflow_ptr, + ARMword sign_mask) +{ + ARMword result = (a1 - a2); + unsigned int ua1 = (unsigned int) a1; + unsigned int ua2 = (unsigned int) a2; + + /* A borrow occurs if a2 is (unsigned) larger than a1. + However the carry flag is *cleared* if a borrow occurs. */ + * borrow_ptr = ! (ua2 > ua1); + + /* Overflow occurs when a negative number is subtracted from a + positive number and the result is negative or a positive + number is subtracted from a negative number and the result is + positive. */ + * overflow_ptr = ( (! (a1 & sign_mask) && (a2 & sign_mask) && (result & sign_mask)) + || ((a1 & sign_mask) && ! (a2 & sign_mask) && ! (result & sign_mask))); + + return result; +} + +static ARMdword +SubS32 (ARMdword a1, ARMdword a2, int * borrow_ptr, int * overflow_ptr) +{ + ARMdword result; + unsigned int ua1; + unsigned int ua2; + + a1 = EXTEND32 (a1); + a2 = EXTEND32 (a2); + + result = a1 - a2; + ua1 = (unsigned int) a1; + ua2 = (unsigned int) a2; + + * borrow_ptr = ! (ua2 > ua1); + + * overflow_ptr = ( (! (a1 & 0x80000000ULL) && (a2 & 0x80000000ULL) && (result & 0x80000000ULL)) + || ((a1 & 0x80000000ULL) && ! (a2 & 0x80000000ULL) && ! (result & 0x80000000ULL))); + + return result; +} + +static ARMword +SubS16 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr) +{ + a1 = EXTEND16 (a1); + a2 = EXTEND16 (a2); + + return Sub32 (a1, a2, carry_ptr, overflow_ptr, 0x8000); +} + +static ARMword +SubS8 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr) +{ + a1 = EXTEND8 (a1); + a2 = EXTEND8 (a2); + + return Sub32 (a1, a2, carry_ptr, overflow_ptr, 0x80); +} + +static ARMword +SubU16 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr) +{ + a1 &= 0xffff; + a2 &= 0xffff; + + return Sub32 (a1, a2, carry_ptr, overflow_ptr, 0x8000); +} + +static ARMword +SubU8 (ARMword a1, ARMword a2, int * carry_ptr, int * overflow_ptr) +{ + a1 &= 0xff; + a2 &= 0xff; + + return Sub32 (a1, a2, carry_ptr, overflow_ptr, 0x80); +} + +static ARMdword +SubU32 (ARMdword a1, ARMdword a2, int * borrow_ptr, int * overflow_ptr) +{ + ARMdword result; + unsigned int ua1; + unsigned int ua2; + + a1 &= 0xffffffff; + a2 &= 0xffffffff; + + result = a1 - a2; + ua1 = (unsigned int) a1; + ua2 = (unsigned int) a2; + + * borrow_ptr = ! (ua2 > ua1); + + * overflow_ptr = ( (! (a1 & 0x80000000ULL) && (a2 & 0x80000000ULL) && (result & 0x80000000ULL)) + || ((a1 & 0x80000000ULL) && ! (a2 & 0x80000000ULL) && ! (result & 0x80000000ULL))); + + return result; +} + +/* For the saturation. */ + +static unsigned char +IwmmxtSaturateU8 (signed short val, int * sat) +{ + unsigned char rv; + + if (val < 0) + { + rv = 0; + *sat = 1; + } + else if (val > 0xff) + { + rv = 0xff; + *sat = 1; + } + else + { + rv = val & 0xff; + *sat = 0; + } + return rv; +} + +static signed char +IwmmxtSaturateS8 (signed short val, int * sat) +{ + signed char rv; + + if (val < -0x80) + { + rv = -0x80; + *sat = 1; + } + else if (val > 0x7f) + { + rv = 0x7f; + *sat = 1; + } + else + { + rv = val & 0xff; + *sat = 0; + } + return rv; +} + +static unsigned short +IwmmxtSaturateU16 (signed int val, int * sat) +{ + unsigned short rv; + + if (val < 0) + { + rv = 0; + *sat = 1; + } + else if (val > 0xffff) + { + rv = 0xffff; + *sat = 1; + } + else + { + rv = val & 0xffff; + *sat = 0; + } + return rv; +} + +static signed short +IwmmxtSaturateS16 (signed int val, int * sat) +{ + signed short rv; + + if (val < -0x8000) + { + rv = - 0x8000; + *sat = 1; + } + else if (val > 0x7fff) + { + rv = 0x7fff; + *sat = 1; + } + else + { + rv = val & 0xffff; + *sat = 0; + } + return rv; +} + +static unsigned long +IwmmxtSaturateU32 (signed long long val, int * sat) +{ + unsigned long rv; + + if (val < 0) + { + rv = 0; + *sat = 1; + } + else if (val > 0xffffffff) + { + rv = 0xffffffff; + *sat = 1; + } + else + { + rv = val & 0xffffffff; + *sat = 0; + } + return rv; +} + +static signed long +IwmmxtSaturateS32 (signed long long val, int * sat) +{ + signed long rv; + + if (val < -0x80000000LL) + { + rv = -0x80000000; + *sat = 1; + } + else if (val > 0x7fffffff) + { + rv = 0x7fffffff; + *sat = 1; + } + else + { + rv = val & 0xffffffff; + *sat = 0; + } + return rv; +} + +/* Intel(r) Wireless MMX(tm) technology Acessor functions. */ + +unsigned +IwmmxtLDC (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword data) +{ + return ARMul_CANT; +} + +unsigned +IwmmxtSTC (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword * data) +{ + return ARMul_CANT; +} + +unsigned +IwmmxtMRC (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword * value) +{ + return ARMul_CANT; +} + +unsigned +IwmmxtMCR (ARMul_State * state ATTRIBUTE_UNUSED, + unsigned type ATTRIBUTE_UNUSED, + ARMword instr, + ARMword value) +{ + return ARMul_CANT; +} + +unsigned +IwmmxtCDP (ARMul_State * state, unsigned type, ARMword instr) +{ + return ARMul_CANT; +} + +/* Intel(r) Wireless MMX(tm) technology instruction implementations. */ + +static int +TANDC (ARMul_State * state, ARMword instr) +{ + ARMword cpsr; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "tandc\n"); +#endif + + /* The Rd field must be r15. */ + if (BITS (12, 15) != 15) + return ARMul_CANT; + + /* The CRn field must be r3. */ + if (BITS (16, 19) != 3) + return ARMul_CANT; + + /* The CRm field must be r0. */ + if (BITS (0, 3) != 0) + return ARMul_CANT; + + cpsr = ARMul_GetCPSR (state) & 0x0fffffff; + + switch (BITS (22, 23)) + { + case Bqual: + cpsr |= ( (wCBITS (wCASF, 28, 31) & wCBITS (wCASF, 24, 27) + & wCBITS (wCASF, 20, 23) & wCBITS (wCASF, 16, 19) + & wCBITS (wCASF, 12, 15) & wCBITS (wCASF, 8, 11) + & wCBITS (wCASF, 4, 7) & wCBITS (wCASF, 0, 3)) << 28); + break; + + case Hqual: + cpsr |= ( (wCBITS (wCASF, 28, 31) & wCBITS (wCASF, 20, 23) + & wCBITS (wCASF, 12, 15) & wCBITS (wCASF, 4, 7)) << 28); + break; + + case Wqual: + cpsr |= ((wCBITS (wCASF, 28, 31) & wCBITS (wCASF, 12, 15)) << 28); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + ARMul_SetCPSR (state, cpsr); + + return ARMul_DONE; +} + +static int +TBCST (ARMul_State * state, ARMword instr) +{ + ARMdword Rn; + int wRd; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "tbcst\n"); +#endif + + Rn = state->Reg [BITS (12, 15)]; + if (BITS (12, 15) == 15) + Rn &= 0xfffffffc; + + wRd = BITS (16, 19); + + switch (BITS (6, 7)) + { + case Bqual: + Rn &= 0xff; + wR [wRd] = (Rn << 56) | (Rn << 48) | (Rn << 40) | (Rn << 32) + | (Rn << 24) | (Rn << 16) | (Rn << 8) | Rn; + break; + + case Hqual: + Rn &= 0xffff; + wR [wRd] = (Rn << 48) | (Rn << 32) | (Rn << 16) | Rn; + break; + + case Wqual: + Rn &= 0xffffffff; + wR [wRd] = (Rn << 32) | Rn; + break; + + default: + ARMul_UndefInstr (state, instr); + break; + } + + wC [wCon] |= WCON_MUP; + return ARMul_DONE; +} + +static int +TEXTRC (ARMul_State * state, ARMword instr) +{ + ARMword cpsr; + ARMword selector; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "textrc\n"); +#endif + + /* The Rd field must be r15. */ + if (BITS (12, 15) != 15) + return ARMul_CANT; + + /* The CRn field must be r3. */ + if (BITS (16, 19) != 3) + return ARMul_CANT; + + /* The CRm field must be 0xxx. */ + if (BIT (3) != 0) + return ARMul_CANT; + + selector = BITS (0, 2); + cpsr = ARMul_GetCPSR (state) & 0x0fffffff; + + switch (BITS (22, 23)) + { + case Bqual: selector *= 4; break; + case Hqual: selector = ((selector & 3) * 8) + 4; break; + case Wqual: selector = ((selector & 1) * 16) + 12; break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + cpsr |= wCBITS (wCASF, selector, selector + 3) << 28; + ARMul_SetCPSR (state, cpsr); + + return ARMul_DONE; +} + +static int +TEXTRM (ARMul_State * state, ARMword instr) +{ + ARMword Rd; + int offset; + int wRn; + int sign; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "textrm\n"); +#endif + + wRn = BITS (16, 19); + sign = BIT (3); + offset = BITS (0, 2); + + switch (BITS (22, 23)) + { + case Bqual: + offset *= 8; + Rd = wRBITS (wRn, offset, offset + 7); + if (sign) + Rd = EXTEND8 (Rd); + break; + + case Hqual: + offset = (offset & 3) * 16; + Rd = wRBITS (wRn, offset, offset + 15); + if (sign) + Rd = EXTEND16 (Rd); + break; + + case Wqual: + offset = (offset & 1) * 32; + Rd = wRBITS (wRn, offset, offset + 31); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + if (BITS (12, 15) == 15) + ARMul_UndefInstr (state, instr); + else + state->Reg [BITS (12, 15)] = Rd; + + return ARMul_DONE; +} + +static int +TINSR (ARMul_State * state, ARMword instr) +{ + ARMdword data; + ARMword offset; + int wRd; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "tinsr\n"); +#endif + + wRd = BITS (16, 19); + data = state->Reg [BITS (12, 15)]; + offset = BITS (0, 2); + + switch (BITS (6, 7)) + { + case Bqual: + data &= 0xff; + switch (offset) + { + case 0: wR [wRd] = data | (wRBITS (wRd, 8, 63) << 8); break; + case 1: wR [wRd] = wRBITS (wRd, 0, 7) | (data << 8) | (wRBITS (wRd, 16, 63) << 16); break; + case 2: wR [wRd] = wRBITS (wRd, 0, 15) | (data << 16) | (wRBITS (wRd, 24, 63) << 24); break; + case 3: wR [wRd] = wRBITS (wRd, 0, 23) | (data << 24) | (wRBITS (wRd, 32, 63) << 32); break; + case 4: wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32) | (wRBITS (wRd, 40, 63) << 40); break; + case 5: wR [wRd] = wRBITS (wRd, 0, 39) | (data << 40) | (wRBITS (wRd, 48, 63) << 48); break; + case 6: wR [wRd] = wRBITS (wRd, 0, 47) | (data << 48) | (wRBITS (wRd, 56, 63) << 56); break; + case 7: wR [wRd] = wRBITS (wRd, 0, 55) | (data << 56); break; + } + break; + + case Hqual: + data &= 0xffff; + + switch (offset & 3) + { + case 0: wR [wRd] = data | (wRBITS (wRd, 16, 63) << 16); break; + case 1: wR [wRd] = wRBITS (wRd, 0, 15) | (data << 16) | (wRBITS (wRd, 32, 63) << 32); break; + case 2: wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32) | (wRBITS (wRd, 48, 63) << 48); break; + case 3: wR [wRd] = wRBITS (wRd, 0, 47) | (data << 48); break; + } + break; + + case Wqual: + if (offset & 1) + wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32); + else + wR [wRd] = (wRBITS (wRd, 32, 63) << 32) | data; + break; + + default: + ARMul_UndefInstr (state, instr); + break; + } + + wC [wCon] |= WCON_MUP; + return ARMul_DONE; +} + +static int +TMCR (ARMul_State * state, ARMword instr) +{ + ARMword val; + int wCreg; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "tmcr\n"); +#endif + + if (BITS (0, 3) != 0) + return ARMul_CANT; + + val = state->Reg [BITS (12, 15)]; + if (BITS (12, 15) == 15) + val &= 0xfffffffc; + + wCreg = BITS (16, 19); + + switch (wCreg) + { + case wCID: + /* The wCID register is read only. */ + break; + + case wCon: + /* Writing to the MUP or CUP bits clears them. */ + wC [wCon] &= ~ (val & 0x3); + break; + + case wCSSF: + /* Only the bottom 8 bits can be written to. + The higher bits write as zero. */ + wC [wCSSF] = (val & 0xff); + wC [wCon] |= WCON_CUP; + break; + + default: + wC [wCreg] = val; + wC [wCon] |= WCON_CUP; + break; + } + + return ARMul_DONE; +} + +static int +TMCRR (ARMul_State * state, ARMword instr) +{ + ARMdword RdHi = state->Reg [BITS (16, 19)]; + ARMword RdLo = state->Reg [BITS (12, 15)]; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "tmcrr\n"); +#endif + + if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15)) + return ARMul_CANT; + + wR [BITS (0, 3)] = (RdHi << 32) | RdLo; + + wC [wCon] |= WCON_MUP; + + return ARMul_DONE; +} + +static int +TMIA (ARMul_State * state, ARMword instr) +{ + signed long long a, b; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "tmia\n"); +#endif + + if ((BITS (0, 3) == 15) || (BITS (12, 15) == 15)) + { + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + a = state->Reg [BITS (0, 3)]; + b = state->Reg [BITS (12, 15)]; + + a = EXTEND32 (a); + b = EXTEND32 (b); + + wR [BITS (5, 8)] += a * b; + wC [wCon] |= WCON_MUP; + + return ARMul_DONE; +} + +static int +TMIAPH (ARMul_State * state, ARMword instr) +{ + signed long a, b, result; + signed long long r; + ARMword Rm = state->Reg [BITS (0, 3)]; + ARMword Rs = state->Reg [BITS (12, 15)]; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "tmiaph\n"); +#endif + + if (BITS (0, 3) == 15 || BITS (12, 15) == 15) + { + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + a = SUBSTR (Rs, ARMword, 16, 31); + b = SUBSTR (Rm, ARMword, 16, 31); + + a = EXTEND16 (a); + b = EXTEND16 (b); + + result = a * b; + + r = result; + r = EXTEND32 (r); + + wR [BITS (5, 8)] += r; + + a = SUBSTR (Rs, ARMword, 0, 15); + b = SUBSTR (Rm, ARMword, 0, 15); + + a = EXTEND16 (a); + b = EXTEND16 (b); + + result = a * b; + + r = result; + r = EXTEND32 (r); + + wR [BITS (5, 8)] += r; + wC [wCon] |= WCON_MUP; + + return ARMul_DONE; +} + +static int +TMIAxy (ARMul_State * state, ARMword instr) +{ + ARMword Rm; + ARMword Rs; + long long temp; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "tmiaxy\n"); +#endif + + if (BITS (0, 3) == 15 || BITS (12, 15) == 15) + { + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + Rm = state->Reg [BITS (0, 3)]; + if (BIT (17)) + Rm >>= 16; + else + Rm &= 0xffff; + + Rs = state->Reg [BITS (12, 15)]; + if (BIT (16)) + Rs >>= 16; + else + Rs &= 0xffff; + + if (Rm & (1 << 15)) + Rm -= 1 << 16; + + if (Rs & (1 << 15)) + Rs -= 1 << 16; + + Rm *= Rs; + temp = Rm; + + if (temp & (1 << 31)) + temp -= 1ULL << 32; + + wR [BITS (5, 8)] += temp; + wC [wCon] |= WCON_MUP; + + return ARMul_DONE; +} + +static int +TMOVMSK (ARMul_State * state, ARMword instr) +{ + ARMdword result; + int wRn; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "tmovmsk\n"); +#endif + + /* The CRm field must be r0. */ + if (BITS (0, 3) != 0) + return ARMul_CANT; + + wRn = BITS (16, 19); + + switch (BITS (22, 23)) + { + case Bqual: + result = ( (wRBITS (wRn, 63, 63) << 7) + | (wRBITS (wRn, 55, 55) << 6) + | (wRBITS (wRn, 47, 47) << 5) + | (wRBITS (wRn, 39, 39) << 4) + | (wRBITS (wRn, 31, 31) << 3) + | (wRBITS (wRn, 23, 23) << 2) + | (wRBITS (wRn, 15, 15) << 1) + | (wRBITS (wRn, 7, 7) << 0)); + break; + + case Hqual: + result = ( (wRBITS (wRn, 63, 63) << 3) + | (wRBITS (wRn, 47, 47) << 2) + | (wRBITS (wRn, 31, 31) << 1) + | (wRBITS (wRn, 15, 15) << 0)); + break; + + case Wqual: + result = (wRBITS (wRn, 63, 63) << 1) | wRBITS (wRn, 31, 31); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + state->Reg [BITS (12, 15)] = result; + + return ARMul_DONE; +} + +static int +TMRC (ARMul_State * state, ARMword instr) +{ + int reg = BITS (12, 15); + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "tmrc\n"); +#endif + + if (BITS (0, 3) != 0) + return ARMul_CANT; + + if (reg == 15) + ARMul_UndefInstr (state, instr); + else + state->Reg [reg] = wC [BITS (16, 19)]; + + return ARMul_DONE; +} + +static int +TMRRC (ARMul_State * state, ARMword instr) +{ + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "tmrrc\n"); +#endif + + if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15) || (BITS (4, 11) != 0)) + ARMul_UndefInstr (state, instr); + else + { + state->Reg [BITS (16, 19)] = wRBITS (BITS (0, 3), 32, 63); + state->Reg [BITS (12, 15)] = wRBITS (BITS (0, 3), 0, 31); + } + + return ARMul_DONE; +} + +static int +TORC (ARMul_State * state, ARMword instr) +{ + ARMword cpsr = ARMul_GetCPSR (state); + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "torc\n"); +#endif + + /* The Rd field must be r15. */ + if (BITS (12, 15) != 15) + return ARMul_CANT; + + /* The CRn field must be r3. */ + if (BITS (16, 19) != 3) + return ARMul_CANT; + + /* The CRm field must be r0. */ + if (BITS (0, 3) != 0) + return ARMul_CANT; + + cpsr &= 0x0fffffff; + + switch (BITS (22, 23)) + { + case Bqual: + cpsr |= ( (wCBITS (wCASF, 28, 31) | wCBITS (wCASF, 24, 27) + | wCBITS (wCASF, 20, 23) | wCBITS (wCASF, 16, 19) + | wCBITS (wCASF, 12, 15) | wCBITS (wCASF, 8, 11) + | wCBITS (wCASF, 4, 7) | wCBITS (wCASF, 0, 3)) << 28); + break; + + case Hqual: + cpsr |= ( (wCBITS (wCASF, 28, 31) | wCBITS (wCASF, 20, 23) + | wCBITS (wCASF, 12, 15) | wCBITS (wCASF, 4, 7)) << 28); + break; + + case Wqual: + cpsr |= ((wCBITS (wCASF, 28, 31) | wCBITS (wCASF, 12, 15)) << 28); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + ARMul_SetCPSR (state, cpsr); + + return ARMul_DONE; +} + +static int +WACC (ARMul_State * state, ARMword instr) +{ + int wRn; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wacc\n"); +#endif + + wRn = BITS (16, 19); + + switch (BITS (22, 23)) + { + case Bqual: + wR [BITS (12, 15)] = + wRBITS (wRn, 56, 63) + wRBITS (wRn, 48, 55) + + wRBITS (wRn, 40, 47) + wRBITS (wRn, 32, 39) + + wRBITS (wRn, 24, 31) + wRBITS (wRn, 16, 23) + + wRBITS (wRn, 8, 15) + wRBITS (wRn, 0, 7); + break; + + case Hqual: + wR [BITS (12, 15)] = + wRBITS (wRn, 48, 63) + wRBITS (wRn, 32, 47) + + wRBITS (wRn, 16, 31) + wRBITS (wRn, 0, 15); + break; + + case Wqual: + wR [BITS (12, 15)] = wRBITS (wRn, 32, 63) + wRBITS (wRn, 0, 31); + break; + + default: + ARMul_UndefInstr (state, instr); + break; + } + + wC [wCon] |= WCON_MUP; + return ARMul_DONE; +} + +static int +WADD (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMdword x; + ARMdword s; + ARMword psr = 0; + int i; + int carry; + int overflow; + int satrv[8]; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wadd\n"); +#endif + + /* Add two numbers using the specified function, + leaving setting the carry bit as required. */ +#define ADDx(x, y, m, f) \ + (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \ + wRBITS (BITS ( 0, 3), (x), (y)) & (m), \ + & carry, & overflow) + + switch (BITS (22, 23)) + { + case Bqual: + for (i = 0; i < 8; i++) + { + switch (BITS (20, 21)) + { + case NoSaturation: + s = ADDx ((i * 8), (i * 8) + 7, 0xff, AddS8); + satrv [BITIDX8 (i)] = 0; + r |= (s & 0xff) << (i * 8); + SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i); + SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i); + SIMD8_SET (psr, carry, SIMD_CBIT, i); + SIMD8_SET (psr, overflow, SIMD_VBIT, i); + break; + + case UnsignedSaturation: + s = ADDx ((i * 8), (i * 8) + 7, 0xff, AddU8); + x = IwmmxtSaturateU8 (s, satrv + BITIDX8 (i)); + r |= (x & 0xff) << (i * 8); + SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i); + SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i); + if (! satrv [BITIDX8 (i)]) + { + SIMD8_SET (psr, carry, SIMD_CBIT, i); + SIMD8_SET (psr, overflow, SIMD_VBIT, i); + } + break; + + case SignedSaturation: + s = ADDx ((i * 8), (i * 8) + 7, 0xff, AddS8); + x = IwmmxtSaturateS8 (s, satrv + BITIDX8 (i)); + r |= (x & 0xff) << (i * 8); + SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i); + SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i); + if (! satrv [BITIDX8 (i)]) + { + SIMD8_SET (psr, carry, SIMD_CBIT, i); + SIMD8_SET (psr, overflow, SIMD_VBIT, i); + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + } + break; + + case Hqual: + satrv[0] = satrv[2] = satrv[4] = satrv[6] = 0; + + for (i = 0; i < 4; i++) + { + switch (BITS (20, 21)) + { + case NoSaturation: + s = ADDx ((i * 16), (i * 16) + 15, 0xffff, AddS16); + satrv [BITIDX16 (i)] = 0; + r |= (s & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + SIMD16_SET (psr, carry, SIMD_CBIT, i); + SIMD16_SET (psr, overflow, SIMD_VBIT, i); + break; + + case UnsignedSaturation: + s = ADDx ((i * 16), (i * 16) + 15, 0xffff, AddU16); + x = IwmmxtSaturateU16 (s, satrv + BITIDX16 (i)); + r |= (x & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (x), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i); + if (! satrv [BITIDX16 (i)]) + { + SIMD16_SET (psr, carry, SIMD_CBIT, i); + SIMD16_SET (psr, overflow, SIMD_VBIT, i); + } + break; + + case SignedSaturation: + s = ADDx ((i * 16), (i * 16) + 15, 0xffff, AddS16); + x = IwmmxtSaturateS16 (s, satrv + BITIDX16 (i)); + r |= (x & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (x), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i); + if (! satrv [BITIDX16 (i)]) + { + SIMD16_SET (psr, carry, SIMD_CBIT, i); + SIMD16_SET (psr, overflow, SIMD_VBIT, i); + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + } + break; + + case Wqual: + satrv[0] = satrv[1] = satrv[2] = satrv[4] = satrv[5] = satrv[6] = 0; + + for (i = 0; i < 2; i++) + { + switch (BITS (20, 21)) + { + case NoSaturation: + s = ADDx ((i * 32), (i * 32) + 31, 0xffffffff, AddS32); + satrv [BITIDX32 (i)] = 0; + r |= (s & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); + SIMD32_SET (psr, carry, SIMD_CBIT, i); + SIMD32_SET (psr, overflow, SIMD_VBIT, i); + break; + + case UnsignedSaturation: + s = ADDx ((i * 32), (i * 32) + 31, 0xffffffff, AddU32); + x = IwmmxtSaturateU32 (s, satrv + BITIDX32 (i)); + r |= (x & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i); + if (! satrv [BITIDX32 (i)]) + { + SIMD32_SET (psr, carry, SIMD_CBIT, i); + SIMD32_SET (psr, overflow, SIMD_VBIT, i); + } + break; + + case SignedSaturation: + s = ADDx ((i * 32), (i * 32) + 31, 0xffffffff, AddS32); + x = IwmmxtSaturateS32 (s, satrv + BITIDX32 (i)); + r |= (x & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i); + if (! satrv [BITIDX32 (i)]) + { + SIMD32_SET (psr, carry, SIMD_CBIT, i); + SIMD32_SET (psr, overflow, SIMD_VBIT, i); + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + wC [wCon] |= (WCON_MUP | WCON_CUP); + + SET_wCSSFvec (satrv); + +#undef ADDx + + return ARMul_DONE; +} + +static int +WALIGNI (ARMword instr) +{ + int shift = BITS (20, 22) * 8; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "waligni\n"); +#endif + + if (shift) + wR [BITS (12, 15)] = + wRBITS (BITS (16, 19), shift, 63) + | (wRBITS (BITS (0, 3), 0, shift) << ((64 - shift))); + else + wR [BITS (12, 15)] = wR [BITS (16, 19)]; + + wC [wCon] |= WCON_MUP; + return ARMul_DONE; +} + +static int +WALIGNR (ARMul_State * state, ARMword instr) +{ + int shift = (wC [BITS (20, 21) + 8] & 0x7) * 8; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "walignr\n"); +#endif + + if (shift) + wR [BITS (12, 15)] = + wRBITS (BITS (16, 19), shift, 63) + | (wRBITS (BITS (0, 3), 0, shift) << ((64 - shift))); + else + wR [BITS (12, 15)] = wR [BITS (16, 19)]; + + wC [wCon] |= WCON_MUP; + return ARMul_DONE; +} + +static int +WAND (ARMword instr) +{ + ARMdword result; + ARMword psr = 0; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wand\n"); +#endif + + result = wR [BITS (16, 19)] & wR [BITS (0, 3)]; + wR [BITS (12, 15)] = result; + + SIMD64_SET (psr, (result == 0), SIMD_ZBIT); + SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT); + + wC [wCASF] = psr; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WANDN (ARMword instr) +{ + ARMdword result; + ARMword psr = 0; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wandn\n"); +#endif + + result = wR [BITS (16, 19)] & ~ wR [BITS (0, 3)]; + wR [BITS (12, 15)] = result; + + SIMD64_SET (psr, (result == 0), SIMD_ZBIT); + SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT); + + wC [wCASF] = psr; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WAVG2 (ARMword instr) +{ + ARMdword r = 0; + ARMword psr = 0; + ARMdword s; + int i; + int round = BIT (20) ? 1 : 0; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wavg2\n"); +#endif + +#define AVG2x(x, y, m) (((wRBITS (BITS (16, 19), (x), (y)) & (m)) \ + + (wRBITS (BITS ( 0, 3), (x), (y)) & (m)) \ + + round) / 2) + + if (BIT (22)) + { + for (i = 0; i < 4; i++) + { + s = AVG2x ((i * 16), (i * 16) + 15, 0xffff) & 0xffff; + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + r |= s << (i * 16); + } + } + else + { + for (i = 0; i < 8; i++) + { + s = AVG2x ((i * 8), (i * 8) + 7, 0xff) & 0xff; + SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i); + r |= s << (i * 8); + } + } + + wR [BITS (12, 15)] = r; + wC [wCASF] = psr; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WCMPEQ (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMword psr = 0; + ARMdword s; + int i; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wcmpeq\n"); +#endif + + switch (BITS (22, 23)) + { + case Bqual: + for (i = 0; i < 8; i++) + { + s = wRBYTE (BITS (16, 19), i) == wRBYTE (BITS (0, 3), i) ? 0xff : 0; + r |= s << (i * 8); + SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i); + SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i); + } + break; + + case Hqual: + for (i = 0; i < 4; i++) + { + s = wRHALF (BITS (16, 19), i) == wRHALF (BITS (0, 3), i) ? 0xffff : 0; + r |= s << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + } + break; + + case Wqual: + for (i = 0; i < 2; i++) + { + s = wRWORD (BITS (16, 19), i) == wRWORD (BITS (0, 3), i) ? 0xffffffff : 0; + r |= s << (i * 32); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WCMPGT (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMword psr = 0; + ARMdword s; + int i; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wcmpgt\n"); +#endif + + switch (BITS (22, 23)) + { + case Bqual: + if (BIT (21)) + { + /* Use a signed comparison. */ + for (i = 0; i < 8; i++) + { + signed char a, b; + + a = wRBYTE (BITS (16, 19), i); + b = wRBYTE (BITS (0, 3), i); + + s = (a > b) ? 0xff : 0; + r |= s << (i * 8); + SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i); + SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i); + } + } + else + { + for (i = 0; i < 8; i++) + { + s = (wRBYTE (BITS (16, 19), i) > wRBYTE (BITS (0, 3), i)) + ? 0xff : 0; + r |= s << (i * 8); + SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i); + SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i); + } + } + break; + + case Hqual: + if (BIT (21)) + { + for (i = 0; i < 4; i++) + { + signed int a, b; + + a = wRHALF (BITS (16, 19), i); + a = EXTEND16 (a); + + b = wRHALF (BITS (0, 3), i); + b = EXTEND16 (b); + + s = (a > b) ? 0xffff : 0; + r |= s << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + } + } + else + { + for (i = 0; i < 4; i++) + { + s = (wRHALF (BITS (16, 19), i) > wRHALF (BITS (0, 3), i)) + ? 0xffff : 0; + r |= s << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + } + } + break; + + case Wqual: + if (BIT (21)) + { + for (i = 0; i < 2; i++) + { + signed long a, b; + + a = wRWORD (BITS (16, 19), i); + b = wRWORD (BITS (0, 3), i); + + s = (a > b) ? 0xffffffff : 0; + r |= s << (i * 32); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); + } + } + else + { + for (i = 0; i < 2; i++) + { + s = (wRWORD (BITS (16, 19), i) > wRWORD (BITS (0, 3), i)) + ? 0xffffffff : 0; + r |= s << (i * 32); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); + } + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static ARMword +Compute_Iwmmxt_Address (ARMul_State * state, ARMword instr, int * pFailed) +{ + ARMword Rn; + ARMword addr; + ARMword offset; + ARMword multiplier; + + * pFailed = 0; + Rn = BITS (16, 19); + addr = state->Reg [Rn]; + offset = BITS (0, 7); + multiplier = BIT (8) ? 4 : 1; + + if (BIT (24)) /* P */ + { + /* Pre Indexed Addressing. */ + if (BIT (23)) + addr += offset * multiplier; + else + addr -= offset * multiplier; + + /* Immediate Pre-Indexed. */ + if (BIT (21)) /* W */ + { + if (Rn == 15) + { + /* Writeback into R15 is UNPREDICTABLE. */ +#ifdef DEBUG + fprintf (stderr, "iWMMXt: writeback into r15\n"); +#endif + * pFailed = 1; + } + else + state->Reg [Rn] = addr; + } + } + else + { + /* Post Indexed Addressing. */ + if (BIT (21)) /* W */ + { + /* Handle the write back of the final address. */ + if (Rn == 15) + { + /* Writeback into R15 is UNPREDICTABLE. */ +#ifdef DEBUG + fprintf (stderr, "iWMMXt: writeback into r15\n"); +#endif + * pFailed = 1; + } + else + { + ARMword increment; + + if (BIT (23)) + increment = offset * multiplier; + else + increment = - (offset * multiplier); + + state->Reg [Rn] = addr + increment; + } + } + else + { + /* P == 0, W == 0, U == 0 is UNPREDICTABLE. */ + if (BIT (23) == 0) + { +#ifdef DEBUG + fprintf (stderr, "iWMMXt: undefined addressing mode\n"); +#endif + * pFailed = 1; + } + } + } + + return addr; +} + +static ARMdword +Iwmmxt_Load_Double_Word (ARMul_State * state, ARMword address) +{ + ARMdword value; + + /* The address must be aligned on a 8 byte boundary. */ + if (address & 0x7) + { + fprintf (stderr, "iWMMXt: At addr 0x%x: Unaligned double word load from 0x%x\n", + (state->Reg[15] - 8) & ~0x3, address); +#ifdef DEBUG +#endif + /* No need to check for alignment traps. An unaligned + double word load with alignment trapping disabled is + UNPREDICTABLE. */ + ARMul_Abort (state, ARMul_DataAbortV); + } + + /* Load the words. */ + if (! state->bigendSig) + { + value = ARMul_LoadWordN (state, address + 4); + value <<= 32; + value |= ARMul_LoadWordN (state, address); + } + else + { + value = ARMul_LoadWordN (state, address); + value <<= 32; + value |= ARMul_LoadWordN (state, address + 4); + } + + /* Check for data aborts. */ + if (state->Aborted) + ARMul_Abort (state, ARMul_DataAbortV); + else + ARMul_Icycles (state, 2, 0L); + + return value; +} + +static ARMword +Iwmmxt_Load_Word (ARMul_State * state, ARMword address) +{ + ARMword value; + + /* Check for a misaligned address. */ + if (address & 3) + { + if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN)) + ARMul_Abort (state, ARMul_DataAbortV); + else + address &= ~ 3; + } + + value = ARMul_LoadWordN (state, address); + + if (state->Aborted) + ARMul_Abort (state, ARMul_DataAbortV); + else + ARMul_Icycles (state, 1, 0L); + + return value; +} + +static ARMword +Iwmmxt_Load_Half_Word (ARMul_State * state, ARMword address) +{ + ARMword value; + + /* Check for a misaligned address. */ + if (address & 1) + { + if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN)) + ARMul_Abort (state, ARMul_DataAbortV); + else + address &= ~ 1; + } + + value = ARMul_LoadHalfWord (state, address); + + if (state->Aborted) + ARMul_Abort (state, ARMul_DataAbortV); + else + ARMul_Icycles (state, 1, 0L); + + return value; +} + +static ARMword +Iwmmxt_Load_Byte (ARMul_State * state, ARMword address) +{ + ARMword value; + + value = ARMul_LoadByte (state, address); + + if (state->Aborted) + ARMul_Abort (state, ARMul_DataAbortV); + else + ARMul_Icycles (state, 1, 0L); + + return value; +} + +static void +Iwmmxt_Store_Double_Word (ARMul_State * state, ARMword address, ARMdword value) +{ + /* The address must be aligned on a 8 byte boundary. */ + if (address & 0x7) + { + fprintf (stderr, "iWMMXt: At addr 0x%x: Unaligned double word store to 0x%x\n", + (state->Reg[15] - 8) & ~0x3, address); +#ifdef DEBUG +#endif + /* No need to check for alignment traps. An unaligned + double word store with alignment trapping disabled is + UNPREDICTABLE. */ + ARMul_Abort (state, ARMul_DataAbortV); + } + + /* Store the words. */ + if (! state->bigendSig) + { + ARMul_StoreWordN (state, address, value); + ARMul_StoreWordN (state, address + 4, value >> 32); + } + else + { + ARMul_StoreWordN (state, address + 4, value); + ARMul_StoreWordN (state, address, value >> 32); + } + + /* Check for data aborts. */ + if (state->Aborted) + ARMul_Abort (state, ARMul_DataAbortV); + else + ARMul_Icycles (state, 2, 0L); +} + +static void +Iwmmxt_Store_Word (ARMul_State * state, ARMword address, ARMword value) +{ + /* Check for a misaligned address. */ + if (address & 3) + { + if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN)) + ARMul_Abort (state, ARMul_DataAbortV); + else + address &= ~ 3; + } + + ARMul_StoreWordN (state, address, value); + + if (state->Aborted) + ARMul_Abort (state, ARMul_DataAbortV); +} + +static void +Iwmmxt_Store_Half_Word (ARMul_State * state, ARMword address, ARMword value) +{ + /* Check for a misaligned address. */ + if (address & 1) + { + if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN)) + ARMul_Abort (state, ARMul_DataAbortV); + else + address &= ~ 1; + } + + ARMul_StoreHalfWord (state, address, value); + + if (state->Aborted) + ARMul_Abort (state, ARMul_DataAbortV); +} + +static void +Iwmmxt_Store_Byte (ARMul_State * state, ARMword address, ARMword value) +{ + ARMul_StoreByte (state, address, value); + + if (state->Aborted) + ARMul_Abort (state, ARMul_DataAbortV); +} + +static int +WLDR (ARMul_State * state, ARMword instr) +{ + ARMword address; + int failed; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wldr\n"); +#endif + + address = Compute_Iwmmxt_Address (state, instr, & failed); + if (failed) + return ARMul_CANT; + + if (BITS (28, 31) == 0xf) + { + /* WLDRW wCx */ + wC [BITS (12, 15)] = Iwmmxt_Load_Word (state, address); + } + else if (BIT (8) == 0) + { + if (BIT (22) == 0) + /* WLDRB */ + wR [BITS (12, 15)] = Iwmmxt_Load_Byte (state, address); + else + /* WLDRH */ + wR [BITS (12, 15)] = Iwmmxt_Load_Half_Word (state, address); + } + else + { + if (BIT (22) == 0) + /* WLDRW wRd */ + wR [BITS (12, 15)] = Iwmmxt_Load_Word (state, address); + else + /* WLDRD */ + wR [BITS (12, 15)] = Iwmmxt_Load_Double_Word (state, address); + } + + wC [wCon] |= WCON_MUP; + + return ARMul_DONE; +} + +static int +WMAC (ARMword instr) +{ + int i; + ARMdword t = 0; + ARMword a, b; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wmac\n"); +#endif + + for (i = 0; i < 4; i++) + { + if (BIT (21)) + { + /* Signed. */ + signed long s; + + a = wRHALF (BITS (16, 19), i); + a = EXTEND16 (a); + + b = wRHALF (BITS (0, 3), i); + b = EXTEND16 (b); + + s = (signed long) a * (signed long) b; + + t = t + (ARMdword) s; + } + else + { + /* Unsigned. */ + a = wRHALF (BITS (16, 19), i); + b = wRHALF (BITS ( 0, 3), i); + + t += a * b; + } + } + + if (BIT (20)) + wR [BITS (12, 15)] = 0; + + if (BIT (21)) /* Signed. */ + wR[BITS (12, 15)] += t; + else + wR [BITS (12, 15)] += t; + + wC [wCon] |= WCON_MUP; + + return ARMul_DONE; +} + +static int +WMADD (ARMword instr) +{ + ARMdword r = 0; + int i; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wmadd\n"); +#endif + + for (i = 0; i < 2; i++) + { + ARMdword s1, s2; + + if (BIT (21)) /* Signed. */ + { + signed long a, b; + + a = wRHALF (BITS (16, 19), i * 2); + a = EXTEND16 (a); + + b = wRHALF (BITS (0, 3), i * 2); + b = EXTEND16 (b); + + s1 = (ARMdword) (a * b); + + a = wRHALF (BITS (16, 19), i * 2 + 1); + a = EXTEND16 (a); + + b = wRHALF (BITS (0, 3), i * 2 + 1); + b = EXTEND16 (b); + + s2 = (ARMdword) (a * b); + } + else /* Unsigned. */ + { + unsigned long a, b; + + a = wRHALF (BITS (16, 19), i * 2); + b = wRHALF (BITS ( 0, 3), i * 2); + + s1 = (ARMdword) (a * b); + + a = wRHALF (BITS (16, 19), i * 2 + 1); + b = wRHALF (BITS ( 0, 3), i * 2 + 1); + + s2 = (ARMdword) a * b; + } + + r |= (ARMdword) ((s1 + s2) & 0xffffffff) << (i ? 32 : 0); + } + + wR [BITS (12, 15)] = r; + wC [wCon] |= WCON_MUP; + + return ARMul_DONE; +} + +static int +WMAX (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMdword s; + int i; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wmax\n"); +#endif + + switch (BITS (22, 23)) + { + case Bqual: + for (i = 0; i < 8; i++) + if (BIT (21)) /* Signed. */ + { + int a, b; + + a = wRBYTE (BITS (16, 19), i); + a = EXTEND8 (a); + + b = wRBYTE (BITS (0, 3), i); + b = EXTEND8 (b); + + if (a > b) + s = a; + else + s = b; + + r |= (s & 0xff) << (i * 8); + } + else /* Unsigned. */ + { + unsigned int a, b; + + a = wRBYTE (BITS (16, 19), i); + b = wRBYTE (BITS (0, 3), i); + + if (a > b) + s = a; + else + s = b; + + r |= (s & 0xff) << (i * 8); + } + break; + + case Hqual: + for (i = 0; i < 4; i++) + if (BIT (21)) /* Signed. */ + { + int a, b; + + a = wRHALF (BITS (16, 19), i); + a = EXTEND16 (a); + + b = wRHALF (BITS (0, 3), i); + b = EXTEND16 (b); + + if (a > b) + s = a; + else + s = b; + + r |= (s & 0xffff) << (i * 16); + } + else /* Unsigned. */ + { + unsigned int a, b; + + a = wRHALF (BITS (16, 19), i); + b = wRHALF (BITS (0, 3), i); + + if (a > b) + s = a; + else + s = b; + + r |= (s & 0xffff) << (i * 16); + } + break; + + case Wqual: + for (i = 0; i < 2; i++) + if (BIT (21)) /* Signed. */ + { + int a, b; + + a = wRWORD (BITS (16, 19), i); + b = wRWORD (BITS (0, 3), i); + + if (a > b) + s = a; + else + s = b; + + r |= (s & 0xffffffff) << (i * 32); + } + else + { + unsigned int a, b; + + a = wRWORD (BITS (16, 19), i); + b = wRWORD (BITS (0, 3), i); + + if (a > b) + s = a; + else + s = b; + + r |= (s & 0xffffffff) << (i * 32); + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wR [BITS (12, 15)] = r; + wC [wCon] |= WCON_MUP; + + return ARMul_DONE; +} + +static int +WMIN (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMdword s; + int i; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wmin\n"); +#endif + + switch (BITS (22, 23)) + { + case Bqual: + for (i = 0; i < 8; i++) + if (BIT (21)) /* Signed. */ + { + int a, b; + + a = wRBYTE (BITS (16, 19), i); + a = EXTEND8 (a); + + b = wRBYTE (BITS (0, 3), i); + b = EXTEND8 (b); + + if (a < b) + s = a; + else + s = b; + + r |= (s & 0xff) << (i * 8); + } + else /* Unsigned. */ + { + unsigned int a, b; + + a = wRBYTE (BITS (16, 19), i); + b = wRBYTE (BITS (0, 3), i); + + if (a < b) + s = a; + else + s = b; + + r |= (s & 0xff) << (i * 8); + } + break; + + case Hqual: + for (i = 0; i < 4; i++) + if (BIT (21)) /* Signed. */ + { + int a, b; + + a = wRHALF (BITS (16, 19), i); + a = EXTEND16 (a); + + b = wRHALF (BITS (0, 3), i); + b = EXTEND16 (b); + + if (a < b) + s = a; + else + s = b; + + r |= (s & 0xffff) << (i * 16); + } + else + { + /* Unsigned. */ + unsigned int a, b; + + a = wRHALF (BITS (16, 19), i); + b = wRHALF (BITS ( 0, 3), i); + + if (a < b) + s = a; + else + s = b; + + r |= (s & 0xffff) << (i * 16); + } + break; + + case Wqual: + for (i = 0; i < 2; i++) + if (BIT (21)) /* Signed. */ + { + int a, b; + + a = wRWORD (BITS (16, 19), i); + b = wRWORD (BITS ( 0, 3), i); + + if (a < b) + s = a; + else + s = b; + + r |= (s & 0xffffffff) << (i * 32); + } + else + { + unsigned int a, b; + + a = wRWORD (BITS (16, 19), i); + b = wRWORD (BITS (0, 3), i); + + if (a < b) + s = a; + else + s = b; + + r |= (s & 0xffffffff) << (i * 32); + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wR [BITS (12, 15)] = r; + wC [wCon] |= WCON_MUP; + + return ARMul_DONE; +} + +static int +WMUL (ARMword instr) +{ + ARMdword r = 0; + ARMdword s; + int i; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wmul\n"); +#endif + + for (i = 0; i < 4; i++) + if (BIT (21)) /* Signed. */ + { + long a, b; + + a = wRHALF (BITS (16, 19), i); + a = EXTEND16 (a); + + b = wRHALF (BITS (0, 3), i); + b = EXTEND16 (b); + + s = a * b; + + if (BIT (20)) + r |= ((s >> 16) & 0xffff) << (i * 16); + else + r |= (s & 0xffff) << (i * 16); + } + else /* Unsigned. */ + { + unsigned long a, b; + + a = wRHALF (BITS (16, 19), i); + b = wRHALF (BITS (0, 3), i); + + s = a * b; + + if (BIT (20)) + r |= ((s >> 16) & 0xffff) << (i * 16); + else + r |= (s & 0xffff) << (i * 16); + } + + wR [BITS (12, 15)] = r; + wC [wCon] |= WCON_MUP; + + return ARMul_DONE; +} + +static int +WOR (ARMword instr) +{ + ARMword psr = 0; + ARMdword result; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wor\n"); +#endif + + result = wR [BITS (16, 19)] | wR [BITS (0, 3)]; + wR [BITS (12, 15)] = result; + + SIMD64_SET (psr, (result == 0), SIMD_ZBIT); + SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT); + + wC [wCASF] = psr; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WPACK (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMword psr = 0; + ARMdword x; + ARMdword s; + int i; + int satrv[8]; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wpack\n"); +#endif + + switch (BITS (22, 23)) + { + case Hqual: + for (i = 0; i < 8; i++) + { + x = wRHALF (i < 4 ? BITS (16, 19) : BITS (0, 3), i & 3); + + switch (BITS (20, 21)) + { + case UnsignedSaturation: + s = IwmmxtSaturateU8 (x, satrv + BITIDX8 (i)); + break; + + case SignedSaturation: + s = IwmmxtSaturateS8 (x, satrv + BITIDX8 (i)); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + r |= (s & 0xff) << (i * 8); + SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i); + SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i); + } + break; + + case Wqual: + satrv[0] = satrv[2] = satrv[4] = satrv[6] = 0; + + for (i = 0; i < 4; i++) + { + x = wRWORD (i < 2 ? BITS (16, 19) : BITS (0, 3), i & 1); + + switch (BITS (20, 21)) + { + case UnsignedSaturation: + s = IwmmxtSaturateU16 (x, satrv + BITIDX16 (i)); + break; + + case SignedSaturation: + s = IwmmxtSaturateS16 (x, satrv + BITIDX16 (i)); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + r |= (s & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + } + break; + + case Dqual: + satrv[0] = satrv[1] = satrv[2] = satrv[4] = satrv[5] = satrv[6] = 0; + + for (i = 0; i < 2; i++) + { + x = wR [i ? BITS (0, 3) : BITS (16, 19)]; + + switch (BITS (20, 21)) + { + case UnsignedSaturation: + s = IwmmxtSaturateU32 (x, satrv + BITIDX32 (i)); + break; + + case SignedSaturation: + s = IwmmxtSaturateS32 (x, satrv + BITIDX32 (i)); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + r |= (s & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + SET_wCSSFvec (satrv); + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WROR (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMdword s; + ARMword psr = 0; + int i; + int shift; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wror\n"); +#endif + + DECODE_G_BIT (state, instr, shift); + + switch (BITS (22, 23)) + { + case Hqual: + shift &= 0xf; + for (i = 0; i < 4; i++) + { + s = ((wRHALF (BITS (16, 19), i) & 0xffff) << (16 - shift)) + | ((wRHALF (BITS (16, 19), i) & 0xffff) >> shift); + r |= (s & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + } + break; + + case Wqual: + shift &= 0x1f; + for (i = 0; i < 2; i++) + { + s = ((wRWORD (BITS (16, 19), i) & 0xffffffff) << (32 - shift)) + | ((wRWORD (BITS (16, 19), i) & 0xffffffff) >> shift); + r |= (s & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); + } + break; + + case Dqual: + shift &= 0x3f; + r = (wR [BITS (16, 19)] >> shift) + | (wR [BITS (16, 19)] << (64 - shift)); + + SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT); + SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WSAD (ARMword instr) +{ + ARMdword r; + int s; + int i; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wsad\n"); +#endif + + /* Z bit. */ + r = BIT (20) ? 0 : (wR [BITS (12, 15)] & 0xffffffff); + + if (BIT (22)) + /* Half. */ + for (i = 0; i < 4; i++) + { + s = (wRHALF (BITS (16, 19), i) - wRHALF (BITS (0, 3), i)); + r += abs (s); + } + else + /* Byte. */ + for (i = 0; i < 8; i++) + { + s = (wRBYTE (BITS (16, 19), i) - wRBYTE (BITS (0, 3), i)); + r += abs (s); + } + + wR [BITS (12, 15)] = r; + wC [wCon] |= WCON_MUP; + + return ARMul_DONE; +} + +static int +WSHUFH (ARMword instr) +{ + ARMdword r = 0; + ARMword psr = 0; + ARMdword s; + int i; + int imm8; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wshufh\n"); +#endif + + imm8 = (BITS (20, 23) << 4) | BITS (0, 3); + + for (i = 0; i < 4; i++) + { + s = wRHALF (BITS (16, 19), ((imm8 >> (i * 2) & 3)) & 0xff); + r |= (s & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WSLL (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMdword s; + ARMword psr = 0; + int i; + unsigned shift; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wsll\n"); +#endif + + DECODE_G_BIT (state, instr, shift); + + switch (BITS (22, 23)) + { + case Hqual: + for (i = 0; i < 4; i++) + { + if (shift > 15) + s = 0; + else + s = ((wRHALF (BITS (16, 19), i) & 0xffff) << shift); + r |= (s & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + } + break; + + case Wqual: + for (i = 0; i < 2; i++) + { + if (shift > 31) + s = 0; + else + s = ((wRWORD (BITS (16, 19), i) & 0xffffffff) << shift); + r |= (s & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); + } + break; + + case Dqual: + if (shift > 63) + r = 0; + else + r = ((wR[BITS (16, 19)] & 0xffffffffffffffffULL) << shift); + + SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT); + SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WSRA (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMdword s; + ARMword psr = 0; + int i; + unsigned shift; + signed long t; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wsra\n"); +#endif + + DECODE_G_BIT (state, instr, shift); + + switch (BITS (22, 23)) + { + case Hqual: + for (i = 0; i < 4; i++) + { + if (shift > 15) + t = (wRHALF (BITS (16, 19), i) & 0x8000) ? 0xffff : 0; + else + { + t = wRHALF (BITS (16, 19), i); + t = EXTEND16 (t); + t >>= shift; + } + + s = t; + r |= (s & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + } + break; + + case Wqual: + for (i = 0; i < 2; i++) + { + if (shift > 31) + t = (wRWORD (BITS (16, 19), i) & 0x80000000) ? 0xffffffff : 0; + else + { + t = wRWORD (BITS (16, 19), i); + t >>= shift; + } + s = t; + r |= (s & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); + } + break; + + case Dqual: + if (shift > 63) + r = (wR [BITS (16, 19)] & 0x8000000000000000ULL) ? 0xffffffffffffffffULL : 0; + else + r = ((signed long long) (wR[BITS (16, 19)] & 0xffffffffffffffffULL) >> shift); + SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT); + SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WSRL (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMdword s; + ARMword psr = 0; + int i; + unsigned int shift; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wsrl\n"); +#endif + + DECODE_G_BIT (state, instr, shift); + + switch (BITS (22, 23)) + { + case Hqual: + for (i = 0; i < 4; i++) + { + if (shift > 15) + s = 0; + else + s = ((unsigned) (wRHALF (BITS (16, 19), i) & 0xffff) >> shift); + + r |= (s & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + } + break; + + case Wqual: + for (i = 0; i < 2; i++) + { + if (shift > 31) + s = 0; + else + s = ((unsigned long) (wRWORD (BITS (16, 19), i) & 0xffffffff) >> shift); + + r |= (s & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); + } + break; + + case Dqual: + if (shift > 63) + r = 0; + else + r = (wR [BITS (16, 19)] & 0xffffffffffffffffULL) >> shift; + + SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT); + SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WSTR (ARMul_State * state, ARMword instr) +{ + ARMword address; + int failed; + + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wstr\n"); +#endif + + address = Compute_Iwmmxt_Address (state, instr, & failed); + if (failed) + return ARMul_CANT; + + if (BITS (28, 31) == 0xf) + { + /* WSTRW wCx */ + Iwmmxt_Store_Word (state, address, wC [BITS (12, 15)]); + } + else if (BIT (8) == 0) + { + if (BIT (22) == 0) + /* WSTRB */ + Iwmmxt_Store_Byte (state, address, wR [BITS (12, 15)]); + else + /* WSTRH */ + Iwmmxt_Store_Half_Word (state, address, wR [BITS (12, 15)]); + } + else + { + if (BIT (22) == 0) + /* WSTRW wRd */ + Iwmmxt_Store_Word (state, address, wR [BITS (12, 15)]); + else + /* WSTRD */ + Iwmmxt_Store_Double_Word (state, address, wR [BITS (12, 15)]); + } + + return ARMul_DONE; +} + +static int +WSUB (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMword psr = 0; + ARMdword x; + ARMdword s; + int i; + int carry; + int overflow; + int satrv[8]; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wsub\n"); +#endif + +/* Subtract two numbers using the specified function, + leaving setting the carry bit as required. */ +#define SUBx(x, y, m, f) \ + (*f) (wRBITS (BITS (16, 19), (x), (y)) & (m), \ + wRBITS (BITS ( 0, 3), (x), (y)) & (m), & carry, & overflow) + + switch (BITS (22, 23)) + { + case Bqual: + for (i = 0; i < 8; i++) + { + switch (BITS (20, 21)) + { + case NoSaturation: + s = SUBx ((i * 8), (i * 8) + 7, 0xff, SubS8); + satrv [BITIDX8 (i)] = 0; + r |= (s & 0xff) << (i * 8); + SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i); + SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i); + SIMD8_SET (psr, carry, SIMD_CBIT, i); + SIMD8_SET (psr, overflow, SIMD_VBIT, i); + break; + + case UnsignedSaturation: + s = SUBx ((i * 8), (i * 8) + 7, 0xff, SubU8); + x = IwmmxtSaturateU8 (s, satrv + BITIDX8 (i)); + r |= (x & 0xff) << (i * 8); + SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i); + SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i); + if (! satrv [BITIDX8 (i)]) + { + SIMD8_SET (psr, carry, SIMD_CBIT, i); + SIMD8_SET (psr, overflow, SIMD_VBIT, i); + } + break; + + case SignedSaturation: + s = SUBx ((i * 8), (i * 8) + 7, 0xff, SubS8); + x = IwmmxtSaturateS8 (s, satrv + BITIDX8 (i)); + r |= (x & 0xff) << (i * 8); + SIMD8_SET (psr, NBIT8 (x), SIMD_NBIT, i); + SIMD8_SET (psr, ZBIT8 (x), SIMD_ZBIT, i); + if (! satrv [BITIDX8 (i)]) + { + SIMD8_SET (psr, carry, SIMD_CBIT, i); + SIMD8_SET (psr, overflow, SIMD_VBIT, i); + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + } + break; + + case Hqual: + satrv[0] = satrv[2] = satrv[4] = satrv[6] = 0; + + for (i = 0; i < 4; i++) + { + switch (BITS (20, 21)) + { + case NoSaturation: + s = SUBx ((i * 16), (i * 16) + 15, 0xffff, SubU16); + satrv [BITIDX16 (i)] = 0; + r |= (s & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + SIMD16_SET (psr, carry, SIMD_CBIT, i); + SIMD16_SET (psr, overflow, SIMD_VBIT, i); + break; + + case UnsignedSaturation: + s = SUBx ((i * 16), (i * 16) + 15, 0xffff, SubU16); + x = IwmmxtSaturateU16 (s, satrv + BITIDX16 (i)); + r |= (x & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (x & 0xffff), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i); + if (! satrv [BITIDX16 (i)]) + { + SIMD16_SET (psr, carry, SIMD_CBIT, i); + SIMD16_SET (psr, overflow, SIMD_VBIT, i); + } + break; + + case SignedSaturation: + s = SUBx ((i * 16), (i * 16) + 15, 0xffff, SubS16); + x = IwmmxtSaturateS16 (s, satrv + BITIDX16 (i)); + r |= (x & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (x), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (x), SIMD_ZBIT, i); + if (! satrv [BITIDX16 (i)]) + { + SIMD16_SET (psr, carry, SIMD_CBIT, i); + SIMD16_SET (psr, overflow, SIMD_VBIT, i); + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + } + break; + + case Wqual: + satrv[0] = satrv[1] = satrv[2] = satrv[4] = satrv[5] = satrv[6] = 0; + + for (i = 0; i < 2; i++) + { + switch (BITS (20, 21)) + { + case NoSaturation: + s = SUBx ((i * 32), (i * 32) + 31, 0xffffffff, SubU32); + satrv[BITIDX32 (i)] = 0; + r |= (s & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); + SIMD32_SET (psr, carry, SIMD_CBIT, i); + SIMD32_SET (psr, overflow, SIMD_VBIT, i); + break; + + case UnsignedSaturation: + s = SUBx ((i * 32), (i * 32) + 31, 0xffffffff, SubU32); + x = IwmmxtSaturateU32 (s, satrv + BITIDX32 (i)); + r |= (x & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i); + if (! satrv [BITIDX32 (i)]) + { + SIMD32_SET (psr, carry, SIMD_CBIT, i); + SIMD32_SET (psr, overflow, SIMD_VBIT, i); + } + break; + + case SignedSaturation: + s = SUBx ((i * 32), (i * 32) + 31, 0xffffffff, SubS32); + x = IwmmxtSaturateS32 (s, satrv + BITIDX32 (i)); + r |= (x & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (x), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (x), SIMD_ZBIT, i); + if (! satrv [BITIDX32 (i)]) + { + SIMD32_SET (psr, carry, SIMD_CBIT, i); + SIMD32_SET (psr, overflow, SIMD_VBIT, i); + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + } + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wR [BITS (12, 15)] = r; + wC [wCASF] = psr; + SET_wCSSFvec (satrv); + wC [wCon] |= (WCON_CUP | WCON_MUP); + +#undef SUBx + + return ARMul_DONE; +} + +static int +WUNPCKEH (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMword psr = 0; + ARMdword s; + int i; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wunpckeh\n"); +#endif + + switch (BITS (22, 23)) + { + case Bqual: + for (i = 0; i < 4; i++) + { + s = wRBYTE (BITS (16, 19), i + 4); + + if (BIT (21) && NBIT8 (s)) + s |= 0xff00; + + r |= (s & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + } + break; + + case Hqual: + for (i = 0; i < 2; i++) + { + s = wRHALF (BITS (16, 19), i + 2); + + if (BIT (21) && NBIT16 (s)) + s |= 0xffff0000; + + r |= (s & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); + } + break; + + case Wqual: + r = wRWORD (BITS (16, 19), 1); + + if (BIT (21) && NBIT32 (r)) + r |= 0xffffffff00000000ULL; + + SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT); + SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WUNPCKEL (ARMul_State * state, ARMword instr) +{ + ARMdword r = 0; + ARMword psr = 0; + ARMdword s; + int i; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wunpckel\n"); +#endif + + switch (BITS (22, 23)) + { + case Bqual: + for (i = 0; i < 4; i++) + { + s = wRBYTE (BITS (16, 19), i); + + if (BIT (21) && NBIT8 (s)) + s |= 0xff00; + + r |= (s & 0xffff) << (i * 16); + SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); + SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); + } + break; + + case Hqual: + for (i = 0; i < 2; i++) + { + s = wRHALF (BITS (16, 19), i); + + if (BIT (21) && NBIT16 (s)) + s |= 0xffff0000; + + r |= (s & 0xffffffff) << (i * 32); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); + } + break; + + case Wqual: + r = wRWORD (BITS (16, 19), 0); + + if (BIT (21) && NBIT32 (r)) + r |= 0xffffffff00000000ULL; + + SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT); + SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WUNPCKIH (ARMul_State * state, ARMword instr) +{ + ARMword a, b; + ARMdword r = 0; + ARMword psr = 0; + ARMdword s; + int i; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wunpckih\n"); +#endif + + switch (BITS (22, 23)) + { + case Bqual: + for (i = 0; i < 4; i++) + { + a = wRBYTE (BITS (16, 19), i + 4); + b = wRBYTE (BITS ( 0, 3), i + 4); + s = a | (b << 8); + r |= (s & 0xffff) << (i * 16); + SIMD8_SET (psr, NBIT8 (a), SIMD_NBIT, i * 2); + SIMD8_SET (psr, ZBIT8 (a), SIMD_ZBIT, i * 2); + SIMD8_SET (psr, NBIT8 (b), SIMD_NBIT, (i * 2) + 1); + SIMD8_SET (psr, ZBIT8 (b), SIMD_ZBIT, (i * 2) + 1); + } + break; + + case Hqual: + for (i = 0; i < 2; i++) + { + a = wRHALF (BITS (16, 19), i + 2); + b = wRHALF (BITS ( 0, 3), i + 2); + s = a | (b << 16); + r |= (s & 0xffffffff) << (i * 32); + SIMD16_SET (psr, NBIT16 (a), SIMD_NBIT, (i * 2)); + SIMD16_SET (psr, ZBIT16 (a), SIMD_ZBIT, (i * 2)); + SIMD16_SET (psr, NBIT16 (b), SIMD_NBIT, (i * 2) + 1); + SIMD16_SET (psr, ZBIT16 (b), SIMD_ZBIT, (i * 2) + 1); + } + break; + + case Wqual: + a = wRWORD (BITS (16, 19), 1); + s = wRWORD (BITS ( 0, 3), 1); + r = a | (s << 32); + + SIMD32_SET (psr, NBIT32 (a), SIMD_NBIT, 0); + SIMD32_SET (psr, ZBIT32 (a), SIMD_ZBIT, 0); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, 1); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, 1); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WUNPCKIL (ARMul_State * state, ARMword instr) +{ + ARMword a, b; + ARMdword r = 0; + ARMword psr = 0; + ARMdword s; + int i; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wunpckil\n"); +#endif + + switch (BITS (22, 23)) + { + case Bqual: + for (i = 0; i < 4; i++) + { + a = wRBYTE (BITS (16, 19), i); + b = wRBYTE (BITS ( 0, 3), i); + s = a | (b << 8); + r |= (s & 0xffff) << (i * 16); + SIMD8_SET (psr, NBIT8 (a), SIMD_NBIT, i * 2); + SIMD8_SET (psr, ZBIT8 (a), SIMD_ZBIT, i * 2); + SIMD8_SET (psr, NBIT8 (b), SIMD_NBIT, (i * 2) + 1); + SIMD8_SET (psr, ZBIT8 (b), SIMD_ZBIT, (i * 2) + 1); + } + break; + + case Hqual: + for (i = 0; i < 2; i++) + { + a = wRHALF (BITS (16, 19), i); + b = wRHALF (BITS ( 0, 3), i); + s = a | (b << 16); + r |= (s & 0xffffffff) << (i * 32); + SIMD16_SET (psr, NBIT16 (a), SIMD_NBIT, (i * 2)); + SIMD16_SET (psr, ZBIT16 (a), SIMD_ZBIT, (i * 2)); + SIMD16_SET (psr, NBIT16 (b), SIMD_NBIT, (i * 2) + 1); + SIMD16_SET (psr, ZBIT16 (b), SIMD_ZBIT, (i * 2) + 1); + } + break; + + case Wqual: + a = wRWORD (BITS (16, 19), 0); + s = wRWORD (BITS ( 0, 3), 0); + r = a | (s << 32); + + SIMD32_SET (psr, NBIT32 (a), SIMD_NBIT, 0); + SIMD32_SET (psr, ZBIT32 (a), SIMD_ZBIT, 0); + SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, 1); + SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, 1); + break; + + default: + ARMul_UndefInstr (state, instr); + return ARMul_DONE; + } + + wC [wCASF] = psr; + wR [BITS (12, 15)] = r; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +static int +WXOR (ARMword instr) +{ + ARMword psr = 0; + ARMdword result; + + if ((read_cp15_reg (15, 0, 1) & 3) != 3) + return ARMul_CANT; + +#ifdef DEBUG + fprintf (stderr, "wxor\n"); +#endif + + result = wR [BITS (16, 19)] ^ wR [BITS (0, 3)]; + wR [BITS (12, 15)] = result; + + SIMD64_SET (psr, (result == 0), SIMD_ZBIT); + SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT); + + wC [wCASF] = psr; + wC [wCon] |= (WCON_CUP | WCON_MUP); + + return ARMul_DONE; +} + +/* This switch table is moved to a seperate function in order + to work around a compiler bug in the host compiler... */ + +static int +Process_Instruction (ARMul_State * state, ARMword instr) +{ + int status = ARMul_BUSY; + + switch ((BITS (20, 23) << 8) | BITS (4, 11)) + { + case 0x000: status = WOR (instr); break; + case 0x011: status = TMCR (state, instr); break; + case 0x100: status = WXOR (instr); break; + case 0x111: status = TMRC (state, instr); break; + case 0x300: status = WANDN (instr); break; + case 0x200: status = WAND (instr); break; + + case 0x810: case 0xa10: + status = WMADD (instr); break; + + case 0x10e: case 0x50e: case 0x90e: case 0xd0e: + status = WUNPCKIL (state, instr); break; + case 0x10c: case 0x50c: case 0x90c: case 0xd0c: + status = WUNPCKIH (state, instr); break; + case 0x012: case 0x112: case 0x412: case 0x512: + status = WSAD (instr); break; + case 0x010: case 0x110: case 0x210: case 0x310: + status = WMUL (instr); break; + case 0x410: case 0x510: case 0x610: case 0x710: + status = WMAC (instr); break; + case 0x006: case 0x406: case 0x806: case 0xc06: + status = WCMPEQ (state, instr); break; + case 0x800: case 0x900: case 0xc00: case 0xd00: + status = WAVG2 (instr); break; + case 0x802: case 0x902: case 0xa02: case 0xb02: + status = WALIGNR (state, instr); break; + case 0x601: case 0x605: case 0x609: case 0x60d: + status = TINSR (state, instr); break; + case 0x107: case 0x507: case 0x907: case 0xd07: + status = TEXTRM (state, instr); break; + case 0x117: case 0x517: case 0x917: case 0xd17: + status = TEXTRC (state, instr); break; + case 0x401: case 0x405: case 0x409: case 0x40d: + status = TBCST (state, instr); break; + case 0x113: case 0x513: case 0x913: case 0xd13: + status = TANDC (state, instr); break; + case 0x01c: case 0x41c: case 0x81c: case 0xc1c: + status = WACC (state, instr); break; + case 0x115: case 0x515: case 0x915: case 0xd15: + status = TORC (state, instr); break; + case 0x103: case 0x503: case 0x903: case 0xd03: + status = TMOVMSK (state, instr); break; + case 0x106: case 0x306: case 0x506: case 0x706: + case 0x906: case 0xb06: case 0xd06: case 0xf06: + status = WCMPGT (state, instr); break; + case 0x00e: case 0x20e: case 0x40e: case 0x60e: + case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e: + status = WUNPCKEL (state, instr); break; + case 0x00c: case 0x20c: case 0x40c: case 0x60c: + case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c: + status = WUNPCKEH (state, instr); break; + case 0x204: case 0x604: case 0xa04: case 0xe04: + case 0x214: case 0x614: case 0xa14: case 0xe14: + status = WSRL (state, instr); break; + case 0x004: case 0x404: case 0x804: case 0xc04: + case 0x014: case 0x414: case 0x814: case 0xc14: + status = WSRA (state, instr); break; + case 0x104: case 0x504: case 0x904: case 0xd04: + case 0x114: case 0x514: case 0x914: case 0xd14: + status = WSLL (state, instr); break; + case 0x304: case 0x704: case 0xb04: case 0xf04: + case 0x314: case 0x714: case 0xb14: case 0xf14: + status = WROR (state, instr); break; + case 0x116: case 0x316: case 0x516: case 0x716: + case 0x916: case 0xb16: case 0xd16: case 0xf16: + status = WMIN (state, instr); break; + case 0x016: case 0x216: case 0x416: case 0x616: + case 0x816: case 0xa16: case 0xc16: case 0xe16: + status = WMAX (state, instr); break; + case 0x002: case 0x102: case 0x202: case 0x302: + case 0x402: case 0x502: case 0x602: case 0x702: + status = WALIGNI (instr); break; + case 0x01a: case 0x11a: case 0x21a: case 0x31a: + case 0x41a: case 0x51a: case 0x61a: case 0x71a: + case 0x81a: case 0x91a: case 0xa1a: case 0xb1a: + case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a: + status = WSUB (state, instr); break; + case 0x01e: case 0x11e: case 0x21e: case 0x31e: + case 0x41e: case 0x51e: case 0x61e: case 0x71e: + case 0x81e: case 0x91e: case 0xa1e: case 0xb1e: + case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e: + status = WSHUFH (instr); break; + case 0x018: case 0x118: case 0x218: case 0x318: + case 0x418: case 0x518: case 0x618: case 0x718: + case 0x818: case 0x918: case 0xa18: case 0xb18: + case 0xc18: case 0xd18: case 0xe18: case 0xf18: + status = WADD (state, instr); break; + case 0x008: case 0x108: case 0x208: case 0x308: + case 0x408: case 0x508: case 0x608: case 0x708: + case 0x808: case 0x908: case 0xa08: case 0xb08: + case 0xc08: case 0xd08: case 0xe08: case 0xf08: + status = WPACK (state, instr); break; + case 0x201: case 0x203: case 0x205: case 0x207: + case 0x209: case 0x20b: case 0x20d: case 0x20f: + case 0x211: case 0x213: case 0x215: case 0x217: + case 0x219: case 0x21b: case 0x21d: case 0x21f: + switch (BITS (16, 19)) + { + case 0x0: status = TMIA (state, instr); break; + case 0x8: status = TMIAPH (state, instr); break; + case 0xc: + case 0xd: + case 0xe: + case 0xf: status = TMIAxy (state, instr); break; + default: break; + } + break; + default: + break; + } + return status; +} + +/* Process a possibly Intel(r) Wireless MMX(tm) technology instruction. + Return true if the instruction was handled. */ + +int +ARMul_HandleIwmmxt (ARMul_State * state, ARMword instr) +{ + int status = ARMul_BUSY; + + if (BITS (24, 27) == 0xe) + { + status = Process_Instruction (state, instr); + } + else if (BITS (25, 27) == 0x6) + { + if (BITS (4, 11) == 0x0 && BITS (20, 24) == 0x4) + status = TMCRR (state, instr); + else if (BITS (9, 11) == 0x0) + { + if (BIT (20) == 0x0) + status = WSTR (state, instr); + else if (BITS (20, 24) == 0x5) + status = TMRRC (state, instr); + else + status = WLDR (state, instr); + } + } + + if (status == ARMul_CANT) + { + /* If the instruction was a recognised but illegal, + perform the abort here rather than returning false. + If we return false then ARMul_MRC may be called which + will still abort, but which also perform the register + transfer... */ + ARMul_Abort (state, ARMul_UndefinedInstrV); + status = ARMul_DONE; + } + + return status == ARMul_DONE; +} + +int +Fetch_Iwmmxt_Register (unsigned int regnum, unsigned char * memory) +{ + if (regnum >= 16) + { + memcpy (memory, wC + (regnum - 16), sizeof wC [0]); + return sizeof wC [0]; + } + else + { + memcpy (memory, wR + regnum, sizeof wR [0]); + return sizeof wR [0]; + } +} + +int +Store_Iwmmxt_Register (unsigned int regnum, unsigned char * memory) +{ + if (regnum >= 16) + { + memcpy (wC + (regnum - 16), memory, sizeof wC [0]); + return sizeof wC [0]; + } + else + { + memcpy (wR + regnum, memory, sizeof wR [0]); + return sizeof wR [0]; + } +}
iwmmxt.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: armdefs.h =================================================================== --- armdefs.h (nonexistent) +++ armdefs.h (revision 816) @@ -0,0 +1,433 @@ +/* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "config.h" +#include +#include + +#define FALSE 0 +#define TRUE 1 +#define LOW 0 +#define HIGH 1 +#define LOWHIGH 1 +#define HIGHLOW 2 + +#ifndef __STDC__ +typedef char *VoidStar; +#endif + +#ifdef HAVE_STDINT_H +#include +typedef uint32_t ARMword; +typedef int32_t ARMsword; +typedef uint64_t ARMdword; +typedef int64_t ARMsdword; +#else +typedef unsigned int ARMword; /* must be 32 bits wide */ +typedef signed int ARMsword; +typedef unsigned long long ARMdword; /* Must be at least 64 bits wide. */ +typedef signed long long ARMsdword; +#endif +typedef struct ARMul_State ARMul_State; + +typedef unsigned ARMul_CPInits (ARMul_State * state); +typedef unsigned ARMul_CPExits (ARMul_State * state); +typedef unsigned ARMul_LDCs (ARMul_State * state, unsigned type, + ARMword instr, ARMword value); +typedef unsigned ARMul_STCs (ARMul_State * state, unsigned type, + ARMword instr, ARMword * value); +typedef unsigned ARMul_MRCs (ARMul_State * state, unsigned type, + ARMword instr, ARMword * value); +typedef unsigned ARMul_MCRs (ARMul_State * state, unsigned type, + ARMword instr, ARMword value); +typedef unsigned ARMul_CDPs (ARMul_State * state, unsigned type, + ARMword instr); +typedef unsigned ARMul_CPReads (ARMul_State * state, unsigned reg, + ARMword * value); +typedef unsigned ARMul_CPWrites (ARMul_State * state, unsigned reg, + ARMword value); + +struct ARMul_State +{ + ARMword Emulate; /* to start and stop emulation */ + unsigned EndCondition; /* reason for stopping */ + unsigned ErrorCode; /* type of illegal instruction */ + ARMword Reg[16]; /* the current register file */ + ARMword RegBank[7][16]; /* all the registers */ + /* 40 bit accumulator. We always keep this 64 bits wide, + and move only 40 bits out of it in an MRA insn. */ + ARMdword Accumulator; + ARMword Cpsr; /* the current psr */ + ARMword Spsr[7]; /* the exception psr's */ + ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags; /* dummy flags for speed */ + ARMword SFlag; +#ifdef MODET + ARMword TFlag; /* Thumb state */ +#endif + ARMword Bank; /* the current register bank */ + ARMword Mode; /* the current mode */ + ARMword instr, pc, temp; /* saved register state */ + ARMword loaded, decoded; /* saved pipeline state */ + unsigned long NumScycles, NumNcycles, NumIcycles, NumCcycles, NumFcycles; /* emulated cycles used */ + unsigned long NumInstrs; /* the number of instructions executed */ + unsigned NextInstr; + unsigned VectorCatch; /* caught exception mask */ + unsigned CallDebug; /* set to call the debugger */ + unsigned CanWatch; /* set by memory interface if its willing to suffer the + overhead of checking for watchpoints on each memory + access */ + unsigned MemReadDebug, MemWriteDebug; + unsigned long StopHandle; + + unsigned char *MemDataPtr; /* admin data */ + unsigned char *MemInPtr; /* the Data In bus */ + unsigned char *MemOutPtr; /* the Data Out bus (which you may not need */ + unsigned char *MemSparePtr; /* extra space */ + ARMword MemSize; + + unsigned char *OSptr; /* OS Handle */ + char *CommandLine; /* Command Line from ARMsd */ + + ARMul_CPInits *CPInit[16]; /* coprocessor initialisers */ + ARMul_CPExits *CPExit[16]; /* coprocessor finalisers */ + ARMul_LDCs *LDC[16]; /* LDC instruction */ + ARMul_STCs *STC[16]; /* STC instruction */ + ARMul_MRCs *MRC[16]; /* MRC instruction */ + ARMul_MCRs *MCR[16]; /* MCR instruction */ + ARMul_CDPs *CDP[16]; /* CDP instruction */ + ARMul_CPReads *CPRead[16]; /* Read CP register */ + ARMul_CPWrites *CPWrite[16]; /* Write CP register */ + unsigned char *CPData[16]; /* Coprocessor data */ + unsigned char const *CPRegWords[16]; /* map of coprocessor register sizes */ + unsigned long LastTime; /* Value of last call to ARMul_Time() */ + ARMword CP14R0_CCD; /* used to count 64 clock cycles with CP14 R0 bit + 3 set */ + + unsigned EventSet; /* the number of events in the queue */ + unsigned long Now; /* time to the nearest cycle */ + struct EventNode **EventPtr; /* the event list */ + + unsigned Exception; /* enable the next four values */ + unsigned Debug; /* show instructions as they are executed */ + unsigned NresetSig; /* reset the processor */ + unsigned NfiqSig; + unsigned NirqSig; + + unsigned abortSig; + unsigned NtransSig; + unsigned bigendSig; + unsigned prog32Sig; + unsigned data32Sig; + unsigned lateabtSig; + ARMword Vector; /* synthesize aborts in cycle modes */ + ARMword Aborted; /* sticky flag for aborts */ + ARMword Reseted; /* sticky flag for Reset */ + ARMword Inted, LastInted; /* sticky flags for interrupts */ + ARMword Base; /* extra hand for base writeback */ + ARMword AbortAddr; /* to keep track of Prefetch aborts */ + + const struct Dbg_HostosInterface *hostif; + + unsigned is_v4; /* Are we emulating a v4 architecture (or higher) ? */ + unsigned is_v5; /* Are we emulating a v5 architecture ? */ + unsigned is_v5e; /* Are we emulating a v5e architecture ? */ + unsigned is_v6; /* Are we emulating a v6 architecture ? */ + unsigned is_XScale; /* Are we emulating an XScale architecture ? */ + unsigned is_iWMMXt; /* Are we emulating an iWMMXt co-processor ? */ + unsigned is_ep9312; /* Are we emulating a Cirrus Maverick co-processor ? */ + unsigned verbose; /* Print various messages like the banner */ +}; + +#define ResetPin NresetSig +#define FIQPin NfiqSig +#define IRQPin NirqSig +#define AbortPin abortSig +#define TransPin NtransSig +#define BigEndPin bigendSig +#define Prog32Pin prog32Sig +#define Data32Pin data32Sig +#define LateAbortPin lateabtSig + +/***************************************************************************\ +* Properties of ARM we know about * +\***************************************************************************/ + +/* The bitflags */ +#define ARM_Fix26_Prop 0x01 +#define ARM_Nexec_Prop 0x02 +#define ARM_Debug_Prop 0x10 +#define ARM_Isync_Prop ARM_Debug_Prop +#define ARM_Lock_Prop 0x20 +#define ARM_v4_Prop 0x40 +#define ARM_v5_Prop 0x80 +#define ARM_v5e_Prop 0x100 +#define ARM_XScale_Prop 0x200 +#define ARM_ep9312_Prop 0x400 +#define ARM_iWMMXt_Prop 0x800 +#define ARM_v6_Prop 0x1000 + +/***************************************************************************\ +* Macros to extract instruction fields * +\***************************************************************************/ + +#define BIT(n) ( (ARMword)(instr>>(n))&1) /* bit n of instruction */ +#define BITS(m,n) ( (ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) ) /* bits m to n of instr */ +#define TOPBITS(n) (instr >> (n)) /* bits 31 to n of instr */ + +/***************************************************************************\ +* The hardware vector addresses * +\***************************************************************************/ + +#define ARMResetV 0L +#define ARMUndefinedInstrV 4L +#define ARMSWIV 8L +#define ARMPrefetchAbortV 12L +#define ARMDataAbortV 16L +#define ARMAddrExceptnV 20L +#define ARMIRQV 24L +#define ARMFIQV 28L +#define ARMErrorV 32L /* This is an offset, not an address ! */ + +#define ARMul_ResetV ARMResetV +#define ARMul_UndefinedInstrV ARMUndefinedInstrV +#define ARMul_SWIV ARMSWIV +#define ARMul_PrefetchAbortV ARMPrefetchAbortV +#define ARMul_DataAbortV ARMDataAbortV +#define ARMul_AddrExceptnV ARMAddrExceptnV +#define ARMul_IRQV ARMIRQV +#define ARMul_FIQV ARMFIQV + +/***************************************************************************\ +* Mode and Bank Constants * +\***************************************************************************/ + +#define USER26MODE 0L +#define FIQ26MODE 1L +#define IRQ26MODE 2L +#define SVC26MODE 3L +#define USER32MODE 16L +#define FIQ32MODE 17L +#define IRQ32MODE 18L +#define SVC32MODE 19L +#define ABORT32MODE 23L +#define UNDEF32MODE 27L +#define SYSTEMMODE 31L + +#define ARM32BITMODE (state->Mode > 3) +#define ARM26BITMODE (state->Mode <= 3) +#define ARMMODE (state->Mode) +#define ARMul_MODEBITS 0x1fL +#define ARMul_MODE32BIT ARM32BITMODE +#define ARMul_MODE26BIT ARM26BITMODE + +#define USERBANK 0 +#define FIQBANK 1 +#define IRQBANK 2 +#define SVCBANK 3 +#define ABORTBANK 4 +#define UNDEFBANK 5 +#define DUMMYBANK 6 +#define SYSTEMBANK USERBANK + +#define BANK_CAN_ACCESS_SPSR(bank) \ + ((bank) != USERBANK && (bank) != SYSTEMBANK && (bank) != DUMMYBANK) + +/***************************************************************************\ +* Definitons of things in the emulator * +\***************************************************************************/ + +extern void ARMul_EmulateInit (void); +extern ARMul_State *ARMul_NewState (void); +extern void ARMul_Reset (ARMul_State * state); +extern ARMword ARMul_DoProg (ARMul_State * state); +extern ARMword ARMul_DoInstr (ARMul_State * state); + +/***************************************************************************\ +* Definitons of things for event handling * +\***************************************************************************/ + +extern void ARMul_ScheduleEvent (ARMul_State * state, unsigned long delay, + unsigned (*func) ()); +extern void ARMul_EnvokeEvent (ARMul_State * state); +extern unsigned long ARMul_Time (ARMul_State * state); + +/***************************************************************************\ +* Useful support routines * +\***************************************************************************/ + +extern ARMword ARMul_GetReg (ARMul_State * state, unsigned mode, + unsigned reg); +extern void ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, + ARMword value); +extern ARMword ARMul_GetPC (ARMul_State * state); +extern ARMword ARMul_GetNextPC (ARMul_State * state); +extern void ARMul_SetPC (ARMul_State * state, ARMword value); +extern ARMword ARMul_GetR15 (ARMul_State * state); +extern void ARMul_SetR15 (ARMul_State * state, ARMword value); + +extern ARMword ARMul_GetCPSR (ARMul_State * state); +extern void ARMul_SetCPSR (ARMul_State * state, ARMword value); +extern ARMword ARMul_GetSPSR (ARMul_State * state, ARMword mode); +extern void ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value); + +/***************************************************************************\ +* Definitons of things to handle aborts * +\***************************************************************************/ + +extern void ARMul_Abort (ARMul_State * state, ARMword address); +#define ARMul_ABORTWORD 0xefffffff /* SWI -1 */ +#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \ + state->AbortAddr = (address & ~3L) +#define ARMul_DATAABORT(address) state->abortSig = HIGH ; \ + state->Aborted = ARMul_DataAbortV ; +#define ARMul_CLEARABORT state->abortSig = LOW + +/***************************************************************************\ +* Definitons of things in the memory interface * +\***************************************************************************/ + +extern unsigned ARMul_MemoryInit (ARMul_State * state, + unsigned long initmemsize); +extern void ARMul_MemoryExit (ARMul_State * state); + +extern ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, + ARMword isize); +extern ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address, + ARMword isize); +extern ARMword ARMul_ReLoadInstr (ARMul_State * state, ARMword address, + ARMword isize); + +extern ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address); +extern ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address); +extern ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address); +extern ARMword ARMul_LoadByte (ARMul_State * state, ARMword address); + +extern void ARMul_StoreWordS (ARMul_State * state, ARMword address, + ARMword data); +extern void ARMul_StoreWordN (ARMul_State * state, ARMword address, + ARMword data); +extern void ARMul_StoreHalfWord (ARMul_State * state, ARMword address, + ARMword data); +extern void ARMul_StoreByte (ARMul_State * state, ARMword address, + ARMword data); + +extern ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, + ARMword data); +extern ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, + ARMword data); + +extern void ARMul_Icycles (ARMul_State * state, unsigned number, + ARMword address); +extern void ARMul_Ccycles (ARMul_State * state, unsigned number, + ARMword address); + +extern ARMword ARMul_ReadWord (ARMul_State * state, ARMword address); +extern ARMword ARMul_ReadByte (ARMul_State * state, ARMword address); +extern ARMword ARMul_SafeReadByte (ARMul_State * state, ARMword address); +extern void ARMul_WriteWord (ARMul_State * state, ARMword address, + ARMword data); +extern void ARMul_WriteByte (ARMul_State * state, ARMword address, + ARMword data); +extern void ARMul_SafeWriteByte (ARMul_State * state, ARMword address, + ARMword data); + +extern ARMword ARMul_MemAccess (ARMul_State * state, ARMword, ARMword, + ARMword, ARMword, ARMword, ARMword, ARMword, + ARMword, ARMword, ARMword); + +/***************************************************************************\ +* Definitons of things in the co-processor interface * +\***************************************************************************/ + +#define ARMul_FIRST 0 +#define ARMul_TRANSFER 1 +#define ARMul_BUSY 2 +#define ARMul_DATA 3 +#define ARMul_INTERRUPT 4 +#define ARMul_DONE 0 +#define ARMul_CANT 1 +#define ARMul_INC 3 + +#define ARMul_CP13_R0_FIQ 0x1 +#define ARMul_CP13_R0_IRQ 0x2 +#define ARMul_CP13_R8_PMUS 0x1 + +#define ARMul_CP14_R0_ENABLE 0x0001 +#define ARMul_CP14_R0_CLKRST 0x0004 +#define ARMul_CP14_R0_CCD 0x0008 +#define ARMul_CP14_R0_INTEN0 0x0010 +#define ARMul_CP14_R0_INTEN1 0x0020 +#define ARMul_CP14_R0_INTEN2 0x0040 +#define ARMul_CP14_R0_FLAG0 0x0100 +#define ARMul_CP14_R0_FLAG1 0x0200 +#define ARMul_CP14_R0_FLAG2 0x0400 +#define ARMul_CP14_R10_MOE_IB 0x0004 +#define ARMul_CP14_R10_MOE_DB 0x0008 +#define ARMul_CP14_R10_MOE_BT 0x000c +#define ARMul_CP15_R1_ENDIAN 0x0080 +#define ARMul_CP15_R1_ALIGN 0x0002 +#define ARMul_CP15_R5_X 0x0400 +#define ARMul_CP15_R5_ST_ALIGN 0x0001 +#define ARMul_CP15_R5_IMPRE 0x0406 +#define ARMul_CP15_R5_MMU_EXCPT 0x0400 +#define ARMul_CP15_DBCON_M 0x0100 +#define ARMul_CP15_DBCON_E1 0x000c +#define ARMul_CP15_DBCON_E0 0x0003 + +extern unsigned ARMul_CoProInit (ARMul_State * state); +extern void ARMul_CoProExit (ARMul_State * state); +extern void ARMul_CoProAttach (ARMul_State * state, unsigned number, + ARMul_CPInits * init, ARMul_CPExits * exit, + ARMul_LDCs * ldc, ARMul_STCs * stc, + ARMul_MRCs * mrc, ARMul_MCRs * mcr, + ARMul_CDPs * cdp, + ARMul_CPReads * read, ARMul_CPWrites * write); +extern void ARMul_CoProDetach (ARMul_State * state, unsigned number); +extern void XScale_check_memacc (ARMul_State * state, ARMword * address, + int store); +extern void XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword far); +extern int XScale_debug_moe (ARMul_State * state, int moe); + +/***************************************************************************\ +* Definitons of things in the host environment * +\***************************************************************************/ + +extern unsigned ARMul_OSInit (ARMul_State * state); +extern void ARMul_OSExit (ARMul_State * state); +extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number); +extern ARMword ARMul_OSLastErrorP (ARMul_State * state); + +extern ARMword ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr); +extern unsigned ARMul_OSException (ARMul_State * state, ARMword vector, + ARMword pc); +extern int rdi_log; + +/***************************************************************************\ +* Host-dependent stuff * +\***************************************************************************/ + +#ifdef macintosh +pascal void SpinCursor (short increment); /* copied from CursorCtl.h */ +# define HOURGLASS SpinCursor( 1 ) +# define HOURGLASS_RATE 1023 /* 2^n - 1 */ +#endif + +extern void ARMul_UndefInstr (ARMul_State *, ARMword); +extern void ARMul_FixCPSR (ARMul_State *, ARMword, ARMword); +extern void ARMul_FixSPSR (ARMul_State *, ARMword, ARMword); +extern void ARMul_ConsolePrint (ARMul_State *, const char *, ...); +extern void ARMul_SelectProcessor (ARMul_State *, unsigned);
armdefs.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: armemu.c =================================================================== --- armemu.c (nonexistent) +++ armemu.c (revision 816) @@ -0,0 +1,5186 @@ +/* armemu.c -- Main instruction emulation: ARM7 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + Modifications to add arch. v4 support by . + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "armdefs.h" +#include "armemu.h" +#include "armos.h" +#include "iwmmxt.h" + +static ARMword GetDPRegRHS (ARMul_State *, ARMword); +static ARMword GetDPSRegRHS (ARMul_State *, ARMword); +static void WriteR15 (ARMul_State *, ARMword); +static void WriteSR15 (ARMul_State *, ARMword); +static void WriteR15Branch (ARMul_State *, ARMword); +static ARMword GetLSRegRHS (ARMul_State *, ARMword); +static ARMword GetLS7RHS (ARMul_State *, ARMword); +static unsigned LoadWord (ARMul_State *, ARMword, ARMword); +static unsigned LoadHalfWord (ARMul_State *, ARMword, ARMword, int); +static unsigned LoadByte (ARMul_State *, ARMword, ARMword, int); +static unsigned StoreWord (ARMul_State *, ARMword, ARMword); +static unsigned StoreHalfWord (ARMul_State *, ARMword, ARMword); +static unsigned StoreByte (ARMul_State *, ARMword, ARMword); +static void LoadMult (ARMul_State *, ARMword, ARMword, ARMword); +static void StoreMult (ARMul_State *, ARMword, ARMword, ARMword); +static void LoadSMult (ARMul_State *, ARMword, ARMword, ARMword); +static void StoreSMult (ARMul_State *, ARMword, ARMword, ARMword); +static unsigned Multiply64 (ARMul_State *, ARMword, int, int); +static unsigned MultiplyAdd64 (ARMul_State *, ARMword, int, int); +static void Handle_Load_Double (ARMul_State *, ARMword); +static void Handle_Store_Double (ARMul_State *, ARMword); + +#define LUNSIGNED (0) /* unsigned operation */ +#define LSIGNED (1) /* signed operation */ +#define LDEFAULT (0) /* default : do nothing */ +#define LSCC (1) /* set condition codes on result */ + +#ifdef NEED_UI_LOOP_HOOK +/* How often to run the ui_loop update, when in use. */ +#define UI_LOOP_POLL_INTERVAL 0x32000 + +/* Counter for the ui_loop_hook update. */ +static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL; + +/* Actual hook to call to run through gdb's gui event loop. */ +extern int (*deprecated_ui_loop_hook) (int); +#endif /* NEED_UI_LOOP_HOOK */ + +extern int stop_simulator; + +/* Short-hand macros for LDR/STR. */ + +/* Store post decrement writeback. */ +#define SHDOWNWB() \ + lhs = LHS ; \ + if (StoreHalfWord (state, instr, lhs)) \ + LSBase = lhs - GetLS7RHS (state, instr); + +/* Store post increment writeback. */ +#define SHUPWB() \ + lhs = LHS ; \ + if (StoreHalfWord (state, instr, lhs)) \ + LSBase = lhs + GetLS7RHS (state, instr); + +/* Store pre decrement. */ +#define SHPREDOWN() \ + (void)StoreHalfWord (state, instr, LHS - GetLS7RHS (state, instr)); + +/* Store pre decrement writeback. */ +#define SHPREDOWNWB() \ + temp = LHS - GetLS7RHS (state, instr); \ + if (StoreHalfWord (state, instr, temp)) \ + LSBase = temp; + +/* Store pre increment. */ +#define SHPREUP() \ + (void)StoreHalfWord (state, instr, LHS + GetLS7RHS (state, instr)); + +/* Store pre increment writeback. */ +#define SHPREUPWB() \ + temp = LHS + GetLS7RHS (state, instr); \ + if (StoreHalfWord (state, instr, temp)) \ + LSBase = temp; + +/* Load post decrement writeback. */ +#define LHPOSTDOWN() \ +{ \ + int done = 1; \ + lhs = LHS; \ + temp = lhs - GetLS7RHS (state, instr); \ + \ + switch (BITS (5, 6)) \ + { \ + case 1: /* H */ \ + if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \ + LSBase = temp; \ + break; \ + case 2: /* SB */ \ + if (LoadByte (state, instr, lhs, LSIGNED)) \ + LSBase = temp; \ + break; \ + case 3: /* SH */ \ + if (LoadHalfWord (state, instr, lhs, LSIGNED)) \ + LSBase = temp; \ + break; \ + case 0: /* SWP handled elsewhere. */ \ + default: \ + done = 0; \ + break; \ + } \ + if (done) \ + break; \ +} + +/* Load post increment writeback. */ +#define LHPOSTUP() \ +{ \ + int done = 1; \ + lhs = LHS; \ + temp = lhs + GetLS7RHS (state, instr); \ + \ + switch (BITS (5, 6)) \ + { \ + case 1: /* H */ \ + if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \ + LSBase = temp; \ + break; \ + case 2: /* SB */ \ + if (LoadByte (state, instr, lhs, LSIGNED)) \ + LSBase = temp; \ + break; \ + case 3: /* SH */ \ + if (LoadHalfWord (state, instr, lhs, LSIGNED)) \ + LSBase = temp; \ + break; \ + case 0: /* SWP handled elsewhere. */ \ + default: \ + done = 0; \ + break; \ + } \ + if (done) \ + break; \ +} + +/* Load pre decrement. */ +#define LHPREDOWN() \ +{ \ + int done = 1; \ + \ + temp = LHS - GetLS7RHS (state, instr); \ + switch (BITS (5, 6)) \ + { \ + case 1: /* H */ \ + (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \ + break; \ + case 2: /* SB */ \ + (void) LoadByte (state, instr, temp, LSIGNED); \ + break; \ + case 3: /* SH */ \ + (void) LoadHalfWord (state, instr, temp, LSIGNED); \ + break; \ + case 0: \ + /* SWP handled elsewhere. */ \ + default: \ + done = 0; \ + break; \ + } \ + if (done) \ + break; \ +} + +/* Load pre decrement writeback. */ +#define LHPREDOWNWB() \ +{ \ + int done = 1; \ + \ + temp = LHS - GetLS7RHS (state, instr); \ + switch (BITS (5, 6)) \ + { \ + case 1: /* H */ \ + if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \ + LSBase = temp; \ + break; \ + case 2: /* SB */ \ + if (LoadByte (state, instr, temp, LSIGNED)) \ + LSBase = temp; \ + break; \ + case 3: /* SH */ \ + if (LoadHalfWord (state, instr, temp, LSIGNED)) \ + LSBase = temp; \ + break; \ + case 0: \ + /* SWP handled elsewhere. */ \ + default: \ + done = 0; \ + break; \ + } \ + if (done) \ + break; \ +} + +/* Load pre increment. */ +#define LHPREUP() \ +{ \ + int done = 1; \ + \ + temp = LHS + GetLS7RHS (state, instr); \ + switch (BITS (5, 6)) \ + { \ + case 1: /* H */ \ + (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \ + break; \ + case 2: /* SB */ \ + (void) LoadByte (state, instr, temp, LSIGNED); \ + break; \ + case 3: /* SH */ \ + (void) LoadHalfWord (state, instr, temp, LSIGNED); \ + break; \ + case 0: \ + /* SWP handled elsewhere. */ \ + default: \ + done = 0; \ + break; \ + } \ + if (done) \ + break; \ +} + +/* Load pre increment writeback. */ +#define LHPREUPWB() \ +{ \ + int done = 1; \ + \ + temp = LHS + GetLS7RHS (state, instr); \ + switch (BITS (5, 6)) \ + { \ + case 1: /* H */ \ + if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \ + LSBase = temp; \ + break; \ + case 2: /* SB */ \ + if (LoadByte (state, instr, temp, LSIGNED)) \ + LSBase = temp; \ + break; \ + case 3: /* SH */ \ + if (LoadHalfWord (state, instr, temp, LSIGNED)) \ + LSBase = temp; \ + break; \ + case 0: \ + /* SWP handled elsewhere. */ \ + default: \ + done = 0; \ + break; \ + } \ + if (done) \ + break; \ +} + +/* Attempt to emulate an ARMv6 instruction. + Returns non-zero upon success. */ + +static int +handle_v6_insn (ARMul_State * state, ARMword instr) +{ + switch (BITS (20, 27)) + { +#if 0 + case 0x03: printf ("Unhandled v6 insn: ldr\n"); break; + case 0x04: printf ("Unhandled v6 insn: umaal\n"); break; + case 0x06: printf ("Unhandled v6 insn: mls/str\n"); break; + case 0x16: printf ("Unhandled v6 insn: smi\n"); break; + case 0x18: printf ("Unhandled v6 insn: strex\n"); break; + case 0x19: printf ("Unhandled v6 insn: ldrex\n"); break; + case 0x1a: printf ("Unhandled v6 insn: strexd\n"); break; + case 0x1b: printf ("Unhandled v6 insn: ldrexd\n"); break; + case 0x1c: printf ("Unhandled v6 insn: strexb\n"); break; + case 0x1d: printf ("Unhandled v6 insn: ldrexb\n"); break; + case 0x1e: printf ("Unhandled v6 insn: strexh\n"); break; + case 0x1f: printf ("Unhandled v6 insn: ldrexh\n"); break; + case 0x30: printf ("Unhandled v6 insn: movw\n"); break; + case 0x32: printf ("Unhandled v6 insn: nop/sev/wfe/wfi/yield\n"); break; + case 0x34: printf ("Unhandled v6 insn: movt\n"); break; + case 0x3f: printf ("Unhandled v6 insn: rbit\n"); break; +#endif + case 0x61: printf ("Unhandled v6 insn: sadd/ssub\n"); break; + case 0x62: printf ("Unhandled v6 insn: qadd/qsub\n"); break; + case 0x63: printf ("Unhandled v6 insn: shadd/shsub\n"); break; + case 0x65: printf ("Unhandled v6 insn: uadd/usub\n"); break; + case 0x66: printf ("Unhandled v6 insn: uqadd/uqsub\n"); break; + case 0x67: printf ("Unhandled v6 insn: uhadd/uhsub\n"); break; + case 0x68: printf ("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); break; + case 0x6c: printf ("Unhandled v6 insn: uxtb16/uxtab16\n"); break; + case 0x70: printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); break; + case 0x74: printf ("Unhandled v6 insn: smlald/smlsld\n"); break; + case 0x75: printf ("Unhandled v6 insn: smmla/smmls/smmul\n"); break; + case 0x78: printf ("Unhandled v6 insn: usad/usada8\n"); break; + case 0x7a: printf ("Unhandled v6 insn: usbfx\n"); break; + case 0x7c: printf ("Unhandled v6 insn: bfc/bfi\n"); break; + + case 0x6a: + { + ARMword Rm; + int ror = -1; + + switch (BITS (4, 11)) + { + case 0x07: ror = 0; break; + case 0x47: ror = 8; break; + case 0x87: ror = 16; break; + case 0xc7: ror = 24; break; + + case 0x01: + case 0xf3: + printf ("Unhandled v6 insn: ssat\n"); + return 0; + default: + break; + } + + if (ror == -1) + { + if (BITS (4, 6) == 0x7) + { + printf ("Unhandled v6 insn: ssat\n"); + return 0; + } + break; + } + + Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF); + if (Rm & 0x80) + Rm |= 0xffffff00; + + if (BITS (16, 19) == 0xf) + /* SXTB */ + state->Reg[BITS (12, 15)] = Rm; + else + /* SXTAB */ + state->Reg[BITS (12, 15)] += Rm; + } + return 1; + + case 0x6b: + { + ARMword Rm; + int ror = -1; + + switch (BITS (4, 11)) + { + case 0x07: ror = 0; break; + case 0x47: ror = 8; break; + case 0x87: ror = 16; break; + case 0xc7: ror = 24; break; + + case 0xfb: + printf ("Unhandled v6 insn: rev\n"); + return 0; + default: + break; + } + + if (ror == -1) + break; + + Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF); + if (Rm & 0x8000) + Rm |= 0xffff0000; + + if (BITS (16, 19) == 0xf) + /* SXTH */ + state->Reg[BITS (12, 15)] = Rm; + else + /* SXTAH */ + state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm; + } + return 1; + + case 0x6e: + { + ARMword Rm; + int ror = -1; + + switch (BITS (4, 11)) + { + case 0x07: ror = 0; break; + case 0x47: ror = 8; break; + case 0x87: ror = 16; break; + case 0xc7: ror = 24; break; + + case 0x01: + case 0xf3: + printf ("Unhandled v6 insn: usat\n"); + return 0; + default: + break; + } + + if (ror == -1) + { + if (BITS (4, 6) == 0x7) + { + printf ("Unhandled v6 insn: usat\n"); + return 0; + } + break; + } + + Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF); + + if (BITS (16, 19) == 0xf) + /* UXTB */ + state->Reg[BITS (12, 15)] = Rm; + else + /* UXTAB */ + state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm; + } + return 1; + + case 0x6f: + { + ARMword Rm; + int ror = -1; + + switch (BITS (4, 11)) + { + case 0x07: ror = 0; break; + case 0x47: ror = 8; break; + case 0x87: ror = 16; break; + case 0xc7: ror = 24; break; + + case 0xfb: + printf ("Unhandled v6 insn: revsh\n"); + return 0; + default: + break; + } + + if (ror == -1) + break; + + Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF); + + if (BITS (16, 19) == 0xf) + /* UXT */ + state->Reg[BITS (12, 15)] = Rm; + else + { + /* UXTAH */ + state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm; + } + } + return 1; + +#if 0 + case 0x84: printf ("Unhandled v6 insn: srs\n"); break; +#endif + default: + break; + } + printf ("Unhandled v6 insn: UNKNOWN: %08x\n", instr); + return 0; +} + +/* EMULATION of ARM6. */ + +/* The PC pipeline value depends on whether ARM + or Thumb instructions are being executed. */ +ARMword isize; + +ARMword +#ifdef MODE32 +ARMul_Emulate32 (ARMul_State * state) +#else +ARMul_Emulate26 (ARMul_State * state) +#endif +{ + ARMword instr; /* The current instruction. */ + ARMword dest = 0; /* Almost the DestBus. */ + ARMword temp; /* Ubiquitous third hand. */ + ARMword pc = 0; /* The address of the current instruction. */ + ARMword lhs; /* Almost the ABus and BBus. */ + ARMword rhs; + ARMword decoded = 0; /* Instruction pipeline. */ + ARMword loaded = 0; + + /* Execute the next instruction. */ + + if (state->NextInstr < PRIMEPIPE) + { + decoded = state->decoded; + loaded = state->loaded; + pc = state->pc; + } + + do + { + /* Just keep going. */ + isize = INSN_SIZE; + + switch (state->NextInstr) + { + case SEQ: + /* Advance the pipeline, and an S cycle. */ + state->Reg[15] += isize; + pc += isize; + instr = decoded; + decoded = loaded; + loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize); + break; + + case NONSEQ: + /* Advance the pipeline, and an N cycle. */ + state->Reg[15] += isize; + pc += isize; + instr = decoded; + decoded = loaded; + loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize); + NORMALCYCLE; + break; + + case PCINCEDSEQ: + /* Program counter advanced, and an S cycle. */ + pc += isize; + instr = decoded; + decoded = loaded; + loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize); + NORMALCYCLE; + break; + + case PCINCEDNONSEQ: + /* Program counter advanced, and an N cycle. */ + pc += isize; + instr = decoded; + decoded = loaded; + loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize); + NORMALCYCLE; + break; + + case RESUME: + /* The program counter has been changed. */ + pc = state->Reg[15]; +#ifndef MODE32 + pc = pc & R15PCBITS; +#endif + state->Reg[15] = pc + (isize * 2); + state->Aborted = 0; + instr = ARMul_ReLoadInstr (state, pc, isize); + decoded = ARMul_ReLoadInstr (state, pc + isize, isize); + loaded = ARMul_ReLoadInstr (state, pc + isize * 2, isize); + NORMALCYCLE; + break; + + default: + /* The program counter has been changed. */ + pc = state->Reg[15]; +#ifndef MODE32 + pc = pc & R15PCBITS; +#endif + state->Reg[15] = pc + (isize * 2); + state->Aborted = 0; + instr = ARMul_LoadInstrN (state, pc, isize); + decoded = ARMul_LoadInstrS (state, pc + (isize), isize); + loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize); + NORMALCYCLE; + break; + } + + if (state->EventSet) + ARMul_EnvokeEvent (state); +#if 0 /* Enable this for a helpful bit of debugging when tracing is needed. */ + fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr); + if (instr == 0) + abort (); +#endif +#if 0 /* Enable this code to help track down stack alignment bugs. */ + { + static ARMword old_sp = -1; + + if (old_sp != state->Reg[13]) + { + old_sp = state->Reg[13]; + fprintf (stderr, "pc: %08x: SP set to %08x%s\n", + pc & ~1, old_sp, (old_sp % 8) ? " [UNALIGNED!]" : ""); + } + } +#endif + + if (state->Exception) + { + /* Any exceptions ? */ + if (state->NresetSig == LOW) + { + ARMul_Abort (state, ARMul_ResetV); + break; + } + else if (!state->NfiqSig && !FFLAG) + { + ARMul_Abort (state, ARMul_FIQV); + break; + } + else if (!state->NirqSig && !IFLAG) + { + ARMul_Abort (state, ARMul_IRQV); + break; + } + } + + if (state->CallDebug > 0) + { + instr = ARMul_Debug (state, pc, instr); + if (state->Emulate < ONCE) + { + state->NextInstr = RESUME; + break; + } + if (state->Debug) + { + fprintf (stderr, "sim: At %08lx Instr %08lx Mode %02lx\n", pc, instr, + state->Mode); + (void) fgetc (stdin); + } + } + else if (state->Emulate < ONCE) + { + state->NextInstr = RESUME; + break; + } + + state->NumInstrs++; + +#ifdef MODET + /* Provide Thumb instruction decoding. If the processor is in Thumb + mode, then we can simply decode the Thumb instruction, and map it + to the corresponding ARM instruction (by directly loading the + instr variable, and letting the normal ARM simulator + execute). There are some caveats to ensure that the correct + pipelined PC value is used when executing Thumb code, and also for + dealing with the BL instruction. */ + if (TFLAG) + { + ARMword new; + + /* Check if in Thumb mode. */ + switch (ARMul_ThumbDecode (state, pc, instr, &new)) + { + case t_undefined: + /* This is a Thumb instruction. */ + ARMul_UndefInstr (state, instr); + goto donext; + + case t_branch: + /* Already processed. */ + goto donext; + + case t_decoded: + /* ARM instruction available. */ + instr = new; + /* So continue instruction decoding. */ + break; + default: + break; + } + } +#endif + + /* Check the condition codes. */ + if ((temp = TOPBITS (28)) == AL) + /* Vile deed in the need for speed. */ + goto mainswitch; + + /* Check the condition code. */ + switch ((int) TOPBITS (28)) + { + case AL: + temp = TRUE; + break; + case NV: + if (state->is_v5) + { + if (BITS (25, 27) == 5) /* BLX(1) */ + { + ARMword dest; + + state->Reg[14] = pc + 4; + + /* Force entry into Thumb mode. */ + dest = pc + 8 + 1; + if (BIT (23)) + dest += (NEGBRANCH + (BIT (24) << 1)); + else + dest += POSBRANCH + (BIT (24) << 1); + + WriteR15Branch (state, dest); + goto donext; + } + else if ((instr & 0xFC70F000) == 0xF450F000) + /* The PLD instruction. Ignored. */ + goto donext; + else if ( ((instr & 0xfe500f00) == 0xfc100100) + || ((instr & 0xfe500f00) == 0xfc000100)) + /* wldrw and wstrw are unconditional. */ + goto mainswitch; + else + /* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2. */ + ARMul_UndefInstr (state, instr); + } + temp = FALSE; + break; + case EQ: + temp = ZFLAG; + break; + case NE: + temp = !ZFLAG; + break; + case VS: + temp = VFLAG; + break; + case VC: + temp = !VFLAG; + break; + case MI: + temp = NFLAG; + break; + case PL: + temp = !NFLAG; + break; + case CS: + temp = CFLAG; + break; + case CC: + temp = !CFLAG; + break; + case HI: + temp = (CFLAG && !ZFLAG); + break; + case LS: + temp = (!CFLAG || ZFLAG); + break; + case GE: + temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); + break; + case LT: + temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); + break; + case GT: + temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG)); + break; + case LE: + temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG; + break; + } /* cc check */ + + /* Handle the Clock counter here. */ + if (state->is_XScale) + { + ARMword cp14r0; + int ok; + + ok = state->CPRead[14] (state, 0, & cp14r0); + + if (ok && (cp14r0 & ARMul_CP14_R0_ENABLE)) + { + unsigned long newcycles, nowtime = ARMul_Time (state); + + newcycles = nowtime - state->LastTime; + state->LastTime = nowtime; + + if (cp14r0 & ARMul_CP14_R0_CCD) + { + if (state->CP14R0_CCD == -1) + state->CP14R0_CCD = newcycles; + else + state->CP14R0_CCD += newcycles; + + if (state->CP14R0_CCD >= 64) + { + newcycles = 0; + + while (state->CP14R0_CCD >= 64) + state->CP14R0_CCD -= 64, newcycles++; + + goto check_PMUintr; + } + } + else + { + ARMword cp14r1; + int do_int = 0; + + state->CP14R0_CCD = -1; +check_PMUintr: + cp14r0 |= ARMul_CP14_R0_FLAG2; + (void) state->CPWrite[14] (state, 0, cp14r0); + + ok = state->CPRead[14] (state, 1, & cp14r1); + + /* Coded like this for portability. */ + while (ok && newcycles) + { + if (cp14r1 == 0xffffffff) + { + cp14r1 = 0; + do_int = 1; + } + else + cp14r1 ++; + + newcycles --; + } + + (void) state->CPWrite[14] (state, 1, cp14r1); + + if (do_int && (cp14r0 & ARMul_CP14_R0_INTEN2)) + { + ARMword temp; + + if (state->CPRead[13] (state, 8, & temp) + && (temp & ARMul_CP13_R8_PMUS)) + ARMul_Abort (state, ARMul_FIQV); + else + ARMul_Abort (state, ARMul_IRQV); + } + } + } + } + + /* Handle hardware instructions breakpoints here. */ + if (state->is_XScale) + { + if ( (pc | 3) == (read_cp15_reg (14, 0, 8) | 2) + || (pc | 3) == (read_cp15_reg (14, 0, 9) | 2)) + { + if (XScale_debug_moe (state, ARMul_CP14_R10_MOE_IB)) + ARMul_OSHandleSWI (state, SWI_Breakpoint); + } + } + + /* Actual execution of instructions begins here. */ + /* If the condition codes don't match, stop here. */ + if (temp) + { + mainswitch: + + if (state->is_XScale) + { + if (BIT (20) == 0 && BITS (25, 27) == 0) + { + if (BITS (4, 7) == 0xD) + { + /* XScale Load Consecutive insn. */ + ARMword temp = GetLS7RHS (state, instr); + ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp; + ARMword addr = BIT (24) ? temp2 : LHS; + + if (BIT (12)) + ARMul_UndefInstr (state, instr); + else if (addr & 7) + /* Alignment violation. */ + ARMul_Abort (state, ARMul_DataAbortV); + else + { + int wb = BIT (21) || (! BIT (24)); + + state->Reg[BITS (12, 15)] = + ARMul_LoadWordN (state, addr); + state->Reg[BITS (12, 15) + 1] = + ARMul_LoadWordN (state, addr + 4); + if (wb) + LSBase = temp2; + } + + goto donext; + } + else if (BITS (4, 7) == 0xF) + { + /* XScale Store Consecutive insn. */ + ARMword temp = GetLS7RHS (state, instr); + ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp; + ARMword addr = BIT (24) ? temp2 : LHS; + + if (BIT (12)) + ARMul_UndefInstr (state, instr); + else if (addr & 7) + /* Alignment violation. */ + ARMul_Abort (state, ARMul_DataAbortV); + else + { + ARMul_StoreWordN (state, addr, + state->Reg[BITS (12, 15)]); + ARMul_StoreWordN (state, addr + 4, + state->Reg[BITS (12, 15) + 1]); + + if (BIT (21)|| ! BIT (24)) + LSBase = temp2; + } + + goto donext; + } + } + + if (ARMul_HandleIwmmxt (state, instr)) + goto donext; + } + + switch ((int) BITS (20, 27)) + { + /* Data Processing Register RHS Instructions. */ + + case 0x00: /* AND reg and MUL */ +#ifdef MODET + if (BITS (4, 11) == 0xB) + { + /* STRH register offset, no write-back, down, post indexed. */ + SHDOWNWB (); + break; + } + if (BITS (4, 7) == 0xD) + { + Handle_Load_Double (state, instr); + break; + } + if (BITS (4, 7) == 0xF) + { + Handle_Store_Double (state, instr); + break; + } +#endif + if (BITS (4, 7) == 9) + { + /* MUL */ + rhs = state->Reg[MULRHSReg]; + if (MULLHSReg == MULDESTReg) + { + UNDEF_MULDestEQOp1; + state->Reg[MULDESTReg] = 0; + } + else if (MULDESTReg != 15) + state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs; + else + UNDEF_MULPCDest; + + for (dest = 0, temp = 0; dest < 32; dest ++) + if (rhs & (1L << dest)) + temp = dest; + + /* Mult takes this many/2 I cycles. */ + ARMul_Icycles (state, ARMul_MultTable[temp], 0L); + } + else + { + /* AND reg. */ + rhs = DPRegRHS; + dest = LHS & rhs; + WRITEDEST (dest); + } + break; + + case 0x01: /* ANDS reg and MULS */ +#ifdef MODET + if ((BITS (4, 11) & 0xF9) == 0x9) + /* LDR register offset, no write-back, down, post indexed. */ + LHPOSTDOWN (); + /* Fall through to rest of decoding. */ +#endif + if (BITS (4, 7) == 9) + { + /* MULS */ + rhs = state->Reg[MULRHSReg]; + + if (MULLHSReg == MULDESTReg) + { + UNDEF_MULDestEQOp1; + state->Reg[MULDESTReg] = 0; + CLEARN; + SETZ; + } + else if (MULDESTReg != 15) + { + dest = state->Reg[MULLHSReg] * rhs; + ARMul_NegZero (state, dest); + state->Reg[MULDESTReg] = dest; + } + else + UNDEF_MULPCDest; + + for (dest = 0, temp = 0; dest < 32; dest ++) + if (rhs & (1L << dest)) + temp = dest; + + /* Mult takes this many/2 I cycles. */ + ARMul_Icycles (state, ARMul_MultTable[temp], 0L); + } + else + { + /* ANDS reg. */ + rhs = DPSRegRHS; + dest = LHS & rhs; + WRITESDEST (dest); + } + break; + + case 0x02: /* EOR reg and MLA */ +#ifdef MODET + if (BITS (4, 11) == 0xB) + { + /* STRH register offset, write-back, down, post indexed. */ + SHDOWNWB (); + break; + } +#endif + if (BITS (4, 7) == 9) + { /* MLA */ + rhs = state->Reg[MULRHSReg]; + if (MULLHSReg == MULDESTReg) + { + UNDEF_MULDestEQOp1; + state->Reg[MULDESTReg] = state->Reg[MULACCReg]; + } + else if (MULDESTReg != 15) + state->Reg[MULDESTReg] = + state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg]; + else + UNDEF_MULPCDest; + + for (dest = 0, temp = 0; dest < 32; dest ++) + if (rhs & (1L << dest)) + temp = dest; + + /* Mult takes this many/2 I cycles. */ + ARMul_Icycles (state, ARMul_MultTable[temp], 0L); + } + else + { + rhs = DPRegRHS; + dest = LHS ^ rhs; + WRITEDEST (dest); + } + break; + + case 0x03: /* EORS reg and MLAS */ +#ifdef MODET + if ((BITS (4, 11) & 0xF9) == 0x9) + /* LDR register offset, write-back, down, post-indexed. */ + LHPOSTDOWN (); + /* Fall through to rest of the decoding. */ +#endif + if (BITS (4, 7) == 9) + { + /* MLAS */ + rhs = state->Reg[MULRHSReg]; + + if (MULLHSReg == MULDESTReg) + { + UNDEF_MULDestEQOp1; + dest = state->Reg[MULACCReg]; + ARMul_NegZero (state, dest); + state->Reg[MULDESTReg] = dest; + } + else if (MULDESTReg != 15) + { + dest = + state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg]; + ARMul_NegZero (state, dest); + state->Reg[MULDESTReg] = dest; + } + else + UNDEF_MULPCDest; + + for (dest = 0, temp = 0; dest < 32; dest ++) + if (rhs & (1L << dest)) + temp = dest; + + /* Mult takes this many/2 I cycles. */ + ARMul_Icycles (state, ARMul_MultTable[temp], 0L); + } + else + { + /* EORS Reg. */ + rhs = DPSRegRHS; + dest = LHS ^ rhs; + WRITESDEST (dest); + } + break; + + case 0x04: /* SUB reg */ +#ifdef MODET + if (BITS (4, 7) == 0xB) + { + /* STRH immediate offset, no write-back, down, post indexed. */ + SHDOWNWB (); + break; + } + if (BITS (4, 7) == 0xD) + { + Handle_Load_Double (state, instr); + break; + } + if (BITS (4, 7) == 0xF) + { + Handle_Store_Double (state, instr); + break; + } +#endif + rhs = DPRegRHS; + dest = LHS - rhs; + WRITEDEST (dest); + break; + + case 0x05: /* SUBS reg */ +#ifdef MODET + if ((BITS (4, 7) & 0x9) == 0x9) + /* LDR immediate offset, no write-back, down, post indexed. */ + LHPOSTDOWN (); + /* Fall through to the rest of the instruction decoding. */ +#endif + lhs = LHS; + rhs = DPRegRHS; + dest = lhs - rhs; + + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) + { + ARMul_SubCarry (state, lhs, rhs, dest); + ARMul_SubOverflow (state, lhs, rhs, dest); + } + else + { + CLEARC; + CLEARV; + } + WRITESDEST (dest); + break; + + case 0x06: /* RSB reg */ +#ifdef MODET + if (BITS (4, 7) == 0xB) + { + /* STRH immediate offset, write-back, down, post indexed. */ + SHDOWNWB (); + break; + } +#endif + rhs = DPRegRHS; + dest = rhs - LHS; + WRITEDEST (dest); + break; + + case 0x07: /* RSBS reg */ +#ifdef MODET + if ((BITS (4, 7) & 0x9) == 0x9) + /* LDR immediate offset, write-back, down, post indexed. */ + LHPOSTDOWN (); + /* Fall through to remainder of instruction decoding. */ +#endif + lhs = LHS; + rhs = DPRegRHS; + dest = rhs - lhs; + + if ((rhs >= lhs) || ((rhs | lhs) >> 31)) + { + ARMul_SubCarry (state, rhs, lhs, dest); + ARMul_SubOverflow (state, rhs, lhs, dest); + } + else + { + CLEARC; + CLEARV; + } + WRITESDEST (dest); + break; + + case 0x08: /* ADD reg */ +#ifdef MODET + if (BITS (4, 11) == 0xB) + { + /* STRH register offset, no write-back, up, post indexed. */ + SHUPWB (); + break; + } + if (BITS (4, 7) == 0xD) + { + Handle_Load_Double (state, instr); + break; + } + if (BITS (4, 7) == 0xF) + { + Handle_Store_Double (state, instr); + break; + } +#endif +#ifdef MODET + if (BITS (4, 7) == 0x9) + { + /* MULL */ + /* 32x32 = 64 */ + ARMul_Icycles (state, + Multiply64 (state, instr, LUNSIGNED, + LDEFAULT), 0L); + break; + } +#endif + rhs = DPRegRHS; + dest = LHS + rhs; + WRITEDEST (dest); + break; + + case 0x09: /* ADDS reg */ +#ifdef MODET + if ((BITS (4, 11) & 0xF9) == 0x9) + /* LDR register offset, no write-back, up, post indexed. */ + LHPOSTUP (); + /* Fall through to remaining instruction decoding. */ +#endif +#ifdef MODET + if (BITS (4, 7) == 0x9) + { + /* MULL */ + /* 32x32=64 */ + ARMul_Icycles (state, + Multiply64 (state, instr, LUNSIGNED, LSCC), + 0L); + break; + } +#endif + lhs = LHS; + rhs = DPRegRHS; + dest = lhs + rhs; + ASSIGNZ (dest == 0); + if ((lhs | rhs) >> 30) + { + /* Possible C,V,N to set. */ + ASSIGNN (NEG (dest)); + ARMul_AddCarry (state, lhs, rhs, dest); + ARMul_AddOverflow (state, lhs, rhs, dest); + } + else + { + CLEARN; + CLEARC; + CLEARV; + } + WRITESDEST (dest); + break; + + case 0x0a: /* ADC reg */ +#ifdef MODET + if (BITS (4, 11) == 0xB) + { + /* STRH register offset, write-back, up, post-indexed. */ + SHUPWB (); + break; + } + if (BITS (4, 7) == 0x9) + { + /* MULL */ + /* 32x32=64 */ + ARMul_Icycles (state, + MultiplyAdd64 (state, instr, LUNSIGNED, + LDEFAULT), 0L); + break; + } +#endif + rhs = DPRegRHS; + dest = LHS + rhs + CFLAG; + WRITEDEST (dest); + break; + + case 0x0b: /* ADCS reg */ +#ifdef MODET + if ((BITS (4, 11) & 0xF9) == 0x9) + /* LDR register offset, write-back, up, post indexed. */ + LHPOSTUP (); + /* Fall through to remaining instruction decoding. */ + if (BITS (4, 7) == 0x9) + { + /* MULL */ + /* 32x32=64 */ + ARMul_Icycles (state, + MultiplyAdd64 (state, instr, LUNSIGNED, + LSCC), 0L); + break; + } +#endif + lhs = LHS; + rhs = DPRegRHS; + dest = lhs + rhs + CFLAG; + ASSIGNZ (dest == 0); + if ((lhs | rhs) >> 30) + { + /* Possible C,V,N to set. */ + ASSIGNN (NEG (dest)); + ARMul_AddCarry (state, lhs, rhs, dest); + ARMul_AddOverflow (state, lhs, rhs, dest); + } + else + { + CLEARN; + CLEARC; + CLEARV; + } + WRITESDEST (dest); + break; + + case 0x0c: /* SBC reg */ +#ifdef MODET + if (BITS (4, 7) == 0xB) + { + /* STRH immediate offset, no write-back, up post indexed. */ + SHUPWB (); + break; + } + if (BITS (4, 7) == 0xD) + { + Handle_Load_Double (state, instr); + break; + } + if (BITS (4, 7) == 0xF) + { + Handle_Store_Double (state, instr); + break; + } + if (BITS (4, 7) == 0x9) + { + /* MULL */ + /* 32x32=64 */ + ARMul_Icycles (state, + Multiply64 (state, instr, LSIGNED, LDEFAULT), + 0L); + break; + } +#endif + rhs = DPRegRHS; + dest = LHS - rhs - !CFLAG; + WRITEDEST (dest); + break; + + case 0x0d: /* SBCS reg */ +#ifdef MODET + if ((BITS (4, 7) & 0x9) == 0x9) + /* LDR immediate offset, no write-back, up, post indexed. */ + LHPOSTUP (); + + if (BITS (4, 7) == 0x9) + { + /* MULL */ + /* 32x32=64 */ + ARMul_Icycles (state, + Multiply64 (state, instr, LSIGNED, LSCC), + 0L); + break; + } +#endif + lhs = LHS; + rhs = DPRegRHS; + dest = lhs - rhs - !CFLAG; + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) + { + ARMul_SubCarry (state, lhs, rhs, dest); + ARMul_SubOverflow (state, lhs, rhs, dest); + } + else + { + CLEARC; + CLEARV; + } + WRITESDEST (dest); + break; + + case 0x0e: /* RSC reg */ +#ifdef MODET + if (BITS (4, 7) == 0xB) + { + /* STRH immediate offset, write-back, up, post indexed. */ + SHUPWB (); + break; + } + + if (BITS (4, 7) == 0x9) + { + /* MULL */ + /* 32x32=64 */ + ARMul_Icycles (state, + MultiplyAdd64 (state, instr, LSIGNED, + LDEFAULT), 0L); + break; + } +#endif + rhs = DPRegRHS; + dest = rhs - LHS - !CFLAG; + WRITEDEST (dest); + break; + + case 0x0f: /* RSCS reg */ +#ifdef MODET + if ((BITS (4, 7) & 0x9) == 0x9) + /* LDR immediate offset, write-back, up, post indexed. */ + LHPOSTUP (); + /* Fall through to remaining instruction decoding. */ + + if (BITS (4, 7) == 0x9) + { + /* MULL */ + /* 32x32=64 */ + ARMul_Icycles (state, + MultiplyAdd64 (state, instr, LSIGNED, LSCC), + 0L); + break; + } +#endif + lhs = LHS; + rhs = DPRegRHS; + dest = rhs - lhs - !CFLAG; + + if ((rhs >= lhs) || ((rhs | lhs) >> 31)) + { + ARMul_SubCarry (state, rhs, lhs, dest); + ARMul_SubOverflow (state, rhs, lhs, dest); + } + else + { + CLEARC; + CLEARV; + } + WRITESDEST (dest); + break; + + case 0x10: /* TST reg and MRS CPSR and SWP word. */ + if (state->is_v5e) + { + if (BIT (4) == 0 && BIT (7) == 1) + { + /* ElSegundo SMLAxy insn. */ + ARMword op1 = state->Reg[BITS (0, 3)]; + ARMword op2 = state->Reg[BITS (8, 11)]; + ARMword Rn = state->Reg[BITS (12, 15)]; + + if (BIT (5)) + op1 >>= 16; + if (BIT (6)) + op2 >>= 16; + op1 &= 0xFFFF; + op2 &= 0xFFFF; + if (op1 & 0x8000) + op1 -= 65536; + if (op2 & 0x8000) + op2 -= 65536; + op1 *= op2; + + if (AddOverflow (op1, Rn, op1 + Rn)) + SETS; + state->Reg[BITS (16, 19)] = op1 + Rn; + break; + } + + if (BITS (4, 11) == 5) + { + /* ElSegundo QADD insn. */ + ARMword op1 = state->Reg[BITS (0, 3)]; + ARMword op2 = state->Reg[BITS (16, 19)]; + ARMword result = op1 + op2; + if (AddOverflow (op1, op2, result)) + { + result = POS (result) ? 0x80000000 : 0x7fffffff; + SETS; + } + state->Reg[BITS (12, 15)] = result; + break; + } + } +#ifdef MODET + if (BITS (4, 11) == 0xB) + { + /* STRH register offset, no write-back, down, pre indexed. */ + SHPREDOWN (); + break; + } + if (BITS (4, 7) == 0xD) + { + Handle_Load_Double (state, instr); + break; + } + if (BITS (4, 7) == 0xF) + { + Handle_Store_Double (state, instr); + break; + } +#endif + if (BITS (4, 11) == 9) + { + /* SWP */ + UNDEF_SWPPC; + temp = LHS; + BUSUSEDINCPCS; +#ifndef MODE32 + if (VECTORACCESS (temp) || ADDREXCEPT (temp)) + { + INTERNALABORT (temp); + (void) ARMul_LoadWordN (state, temp); + (void) ARMul_LoadWordN (state, temp); + } + else +#endif + dest = ARMul_SwapWord (state, temp, state->Reg[RHSReg]); + if (temp & 3) + DEST = ARMul_Align (state, temp, dest); + else + DEST = dest; + if (state->abortSig || state->Aborted) + TAKEABORT; + } + else if ((BITS (0, 11) == 0) && (LHSReg == 15)) + { /* MRS CPSR */ + UNDEF_MRSPC; + DEST = ECC | EINT | EMODE; + } + else + { + UNDEF_Test; + } + break; + + case 0x11: /* TSTP reg */ +#ifdef MODET + if ((BITS (4, 11) & 0xF9) == 0x9) + /* LDR register offset, no write-back, down, pre indexed. */ + LHPREDOWN (); + /* Continue with remaining instruction decode. */ +#endif + if (DESTReg == 15) + { + /* TSTP reg */ +#ifdef MODE32 + state->Cpsr = GETSPSR (state->Bank); + ARMul_CPSRAltered (state); +#else + rhs = DPRegRHS; + temp = LHS & rhs; + SETR15PSR (temp); +#endif + } + else + { + /* TST reg */ + rhs = DPSRegRHS; + dest = LHS & rhs; + ARMul_NegZero (state, dest); + } + break; + + case 0x12: /* TEQ reg and MSR reg to CPSR (ARM6). */ + if (state->is_v5) + { + if (BITS (4, 7) == 3) + { + /* BLX(2) */ + ARMword temp; + + if (TFLAG) + temp = (pc + 2) | 1; + else + temp = pc + 4; + + WriteR15Branch (state, state->Reg[RHSReg]); + state->Reg[14] = temp; + break; + } + } + + if (state->is_v5e) + { + if (BIT (4) == 0 && BIT (7) == 1 + && (BIT (5) == 0 || BITS (12, 15) == 0)) + { + /* ElSegundo SMLAWy/SMULWy insn. */ + ARMdword op1 = state->Reg[BITS (0, 3)]; + ARMdword op2 = state->Reg[BITS (8, 11)]; + ARMdword result; + + if (BIT (6)) + op2 >>= 16; + if (op1 & 0x80000000) + op1 -= 1ULL << 32; + op2 &= 0xFFFF; + if (op2 & 0x8000) + op2 -= 65536; + result = (op1 * op2) >> 16; + + if (BIT (5) == 0) + { + ARMword Rn = state->Reg[BITS (12, 15)]; + + if (AddOverflow (result, Rn, result + Rn)) + SETS; + result += Rn; + } + state->Reg[BITS (16, 19)] = result; + break; + } + + if (BITS (4, 11) == 5) + { + /* ElSegundo QSUB insn. */ + ARMword op1 = state->Reg[BITS (0, 3)]; + ARMword op2 = state->Reg[BITS (16, 19)]; + ARMword result = op1 - op2; + + if (SubOverflow (op1, op2, result)) + { + result = POS (result) ? 0x80000000 : 0x7fffffff; + SETS; + } + + state->Reg[BITS (12, 15)] = result; + break; + } + } +#ifdef MODET + if (BITS (4, 11) == 0xB) + { + /* STRH register offset, write-back, down, pre indexed. */ + SHPREDOWNWB (); + break; + } + if (BITS (4, 27) == 0x12FFF1) + { + /* BX */ + WriteR15Branch (state, state->Reg[RHSReg]); + break; + } + if (BITS (4, 7) == 0xD) + { + Handle_Load_Double (state, instr); + break; + } + if (BITS (4, 7) == 0xF) + { + Handle_Store_Double (state, instr); + break; + } +#endif + if (state->is_v5) + { + if (BITS (4, 7) == 0x7) + { + ARMword value; + extern int SWI_vector_installed; + + /* Hardware is allowed to optionally override this + instruction and treat it as a breakpoint. Since + this is a simulator not hardware, we take the position + that if a SWI vector was not installed, then an Abort + vector was probably not installed either, and so + normally this instruction would be ignored, even if an + Abort is generated. This is a bad thing, since GDB + uses this instruction for its breakpoints (at least in + Thumb mode it does). So intercept the instruction here + and generate a breakpoint SWI instead. */ + if (! SWI_vector_installed) + ARMul_OSHandleSWI (state, SWI_Breakpoint); + else + { + /* BKPT - normally this will cause an abort, but on the + XScale we must check the DCSR. */ + XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc); + if (!XScale_debug_moe (state, ARMul_CP14_R10_MOE_BT)) + break; + } + + /* Force the next instruction to be refetched. */ + state->NextInstr = RESUME; + break; + } + } + if (DESTReg == 15) + { + /* MSR reg to CPSR. */ + UNDEF_MSRPC; + temp = DPRegRHS; +#ifdef MODET + /* Don't allow TBIT to be set by MSR. */ + temp &= ~ TBIT; +#endif + ARMul_FixCPSR (state, instr, temp); + } + else + UNDEF_Test; + + break; + + case 0x13: /* TEQP reg */ +#ifdef MODET + if ((BITS (4, 11) & 0xF9) == 0x9) + /* LDR register offset, write-back, down, pre indexed. */ + LHPREDOWNWB (); + /* Continue with remaining instruction decode. */ +#endif + if (DESTReg == 15) + { + /* TEQP reg */ +#ifdef MODE32 + state->Cpsr = GETSPSR (state->Bank); + ARMul_CPSRAltered (state); +#else + rhs = DPRegRHS; + temp = LHS ^ rhs; + SETR15PSR (temp); +#endif + } + else + { + /* TEQ Reg. */ + rhs = DPSRegRHS; + dest = LHS ^ rhs; + ARMul_NegZero (state, dest); + } + break; + + case 0x14: /* CMP reg and MRS SPSR and SWP byte. */ + if (state->is_v5e) + { + if (BIT (4) == 0 && BIT (7) == 1) + { + /* ElSegundo SMLALxy insn. */ + ARMdword op1 = state->Reg[BITS (0, 3)]; + ARMdword op2 = state->Reg[BITS (8, 11)]; + ARMdword dest; + ARMdword result; + + if (BIT (5)) + op1 >>= 16; + if (BIT (6)) + op2 >>= 16; + op1 &= 0xFFFF; + if (op1 & 0x8000) + op1 -= 65536; + op2 &= 0xFFFF; + if (op2 & 0x8000) + op2 -= 65536; + + dest = (ARMdword) state->Reg[BITS (16, 19)] << 32; + dest |= state->Reg[BITS (12, 15)]; + dest += op1 * op2; + state->Reg[BITS (12, 15)] = dest; + state->Reg[BITS (16, 19)] = dest >> 32; + break; + } + + if (BITS (4, 11) == 5) + { + /* ElSegundo QDADD insn. */ + ARMword op1 = state->Reg[BITS (0, 3)]; + ARMword op2 = state->Reg[BITS (16, 19)]; + ARMword op2d = op2 + op2; + ARMword result; + + if (AddOverflow (op2, op2, op2d)) + { + SETS; + op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; + } + + result = op1 + op2d; + if (AddOverflow (op1, op2d, result)) + { + SETS; + result = POS (result) ? 0x80000000 : 0x7fffffff; + } + + state->Reg[BITS (12, 15)] = result; + break; + } + } +#ifdef MODET + if (BITS (4, 7) == 0xB) + { + /* STRH immediate offset, no write-back, down, pre indexed. */ + SHPREDOWN (); + break; + } + if (BITS (4, 7) == 0xD) + { + Handle_Load_Double (state, instr); + break; + } + if (BITS (4, 7) == 0xF) + { + Handle_Store_Double (state, instr); + break; + } +#endif + if (BITS (4, 11) == 9) + { + /* SWP */ + UNDEF_SWPPC; + temp = LHS; + BUSUSEDINCPCS; +#ifndef MODE32 + if (VECTORACCESS (temp) || ADDREXCEPT (temp)) + { + INTERNALABORT (temp); + (void) ARMul_LoadByte (state, temp); + (void) ARMul_LoadByte (state, temp); + } + else +#endif + DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]); + if (state->abortSig || state->Aborted) + TAKEABORT; + } + else if ((BITS (0, 11) == 0) && (LHSReg == 15)) + { + /* MRS SPSR */ + UNDEF_MRSPC; + DEST = GETSPSR (state->Bank); + } + else + UNDEF_Test; + + break; + + case 0x15: /* CMPP reg. */ +#ifdef MODET + if ((BITS (4, 7) & 0x9) == 0x9) + /* LDR immediate offset, no write-back, down, pre indexed. */ + LHPREDOWN (); + /* Continue with remaining instruction decode. */ +#endif + if (DESTReg == 15) + { + /* CMPP reg. */ +#ifdef MODE32 + state->Cpsr = GETSPSR (state->Bank); + ARMul_CPSRAltered (state); +#else + rhs = DPRegRHS; + temp = LHS - rhs; + SETR15PSR (temp); +#endif + } + else + { + /* CMP reg. */ + lhs = LHS; + rhs = DPRegRHS; + dest = lhs - rhs; + ARMul_NegZero (state, dest); + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) + { + ARMul_SubCarry (state, lhs, rhs, dest); + ARMul_SubOverflow (state, lhs, rhs, dest); + } + else + { + CLEARC; + CLEARV; + } + } + break; + + case 0x16: /* CMN reg and MSR reg to SPSR */ + if (state->is_v5e) + { + if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0) + { + /* ElSegundo SMULxy insn. */ + ARMword op1 = state->Reg[BITS (0, 3)]; + ARMword op2 = state->Reg[BITS (8, 11)]; + ARMword Rn = state->Reg[BITS (12, 15)]; + + if (BIT (5)) + op1 >>= 16; + if (BIT (6)) + op2 >>= 16; + op1 &= 0xFFFF; + op2 &= 0xFFFF; + if (op1 & 0x8000) + op1 -= 65536; + if (op2 & 0x8000) + op2 -= 65536; + + state->Reg[BITS (16, 19)] = op1 * op2; + break; + } + + if (BITS (4, 11) == 5) + { + /* ElSegundo QDSUB insn. */ + ARMword op1 = state->Reg[BITS (0, 3)]; + ARMword op2 = state->Reg[BITS (16, 19)]; + ARMword op2d = op2 + op2; + ARMword result; + + if (AddOverflow (op2, op2, op2d)) + { + SETS; + op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; + } + + result = op1 - op2d; + if (SubOverflow (op1, op2d, result)) + { + SETS; + result = POS (result) ? 0x80000000 : 0x7fffffff; + } + + state->Reg[BITS (12, 15)] = result; + break; + } + } + + if (state->is_v5) + { + if (BITS (4, 11) == 0xF1 && BITS (16, 19) == 0xF) + { + /* ARM5 CLZ insn. */ + ARMword op1 = state->Reg[BITS (0, 3)]; + int result = 32; + + if (op1) + for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1) + result++; + + state->Reg[BITS (12, 15)] = result; + break; + } + } +#ifdef MODET + if (BITS (4, 7) == 0xB) + { + /* STRH immediate offset, write-back, down, pre indexed. */ + SHPREDOWNWB (); + break; + } + if (BITS (4, 7) == 0xD) + { + Handle_Load_Double (state, instr); + break; + } + if (BITS (4, 7) == 0xF) + { + Handle_Store_Double (state, instr); + break; + } +#endif + if (DESTReg == 15) + { + /* MSR */ + UNDEF_MSRPC; + ARMul_FixSPSR (state, instr, DPRegRHS); + } + else + { + UNDEF_Test; + } + break; + + case 0x17: /* CMNP reg */ +#ifdef MODET + if ((BITS (4, 7) & 0x9) == 0x9) + /* LDR immediate offset, write-back, down, pre indexed. */ + LHPREDOWNWB (); + /* Continue with remaining instruction decoding. */ +#endif + if (DESTReg == 15) + { +#ifdef MODE32 + state->Cpsr = GETSPSR (state->Bank); + ARMul_CPSRAltered (state); +#else + rhs = DPRegRHS; + temp = LHS + rhs; + SETR15PSR (temp); +#endif + break; + } + else + { + /* CMN reg. */ + lhs = LHS; + rhs = DPRegRHS; + dest = lhs + rhs; + ASSIGNZ (dest == 0); + if ((lhs | rhs) >> 30) + { + /* Possible C,V,N to set. */ + ASSIGNN (NEG (dest)); + ARMul_AddCarry (state, lhs, rhs, dest); + ARMul_AddOverflow (state, lhs, rhs, dest); + } + else + { + CLEARN; + CLEARC; + CLEARV; + } + } + break; + + case 0x18: /* ORR reg */ +#ifdef MODET + if (BITS (4, 11) == 0xB) + { + /* STRH register offset, no write-back, up, pre indexed. */ + SHPREUP (); + break; + } + if (BITS (4, 7) == 0xD) + { + Handle_Load_Double (state, instr); + break; + } + if (BITS (4, 7) == 0xF) + { + Handle_Store_Double (state, instr); + break; + } +#endif + rhs = DPRegRHS; + dest = LHS | rhs; + WRITEDEST (dest); + break; + + case 0x19: /* ORRS reg */ +#ifdef MODET + if ((BITS (4, 11) & 0xF9) == 0x9) + /* LDR register offset, no write-back, up, pre indexed. */ + LHPREUP (); + /* Continue with remaining instruction decoding. */ +#endif + rhs = DPSRegRHS; + dest = LHS | rhs; + WRITESDEST (dest); + break; + + case 0x1a: /* MOV reg */ +#ifdef MODET + if (BITS (4, 11) == 0xB) + { + /* STRH register offset, write-back, up, pre indexed. */ + SHPREUPWB (); + break; + } + if (BITS (4, 7) == 0xD) + { + Handle_Load_Double (state, instr); + break; + } + if (BITS (4, 7) == 0xF) + { + Handle_Store_Double (state, instr); + break; + } +#endif + dest = DPRegRHS; + WRITEDEST (dest); + break; + + case 0x1b: /* MOVS reg */ +#ifdef MODET + if ((BITS (4, 11) & 0xF9) == 0x9) + /* LDR register offset, write-back, up, pre indexed. */ + LHPREUPWB (); + /* Continue with remaining instruction decoding. */ +#endif + dest = DPSRegRHS; + WRITESDEST (dest); + break; + + case 0x1c: /* BIC reg */ +#ifdef MODET + if (BITS (4, 7) == 0xB) + { + /* STRH immediate offset, no write-back, up, pre indexed. */ + SHPREUP (); + break; + } + if (BITS (4, 7) == 0xD) + { + Handle_Load_Double (state, instr); + break; + } + else if (BITS (4, 7) == 0xF) + { + Handle_Store_Double (state, instr); + break; + } +#endif + rhs = DPRegRHS; + dest = LHS & ~rhs; + WRITEDEST (dest); + break; + + case 0x1d: /* BICS reg */ +#ifdef MODET + if ((BITS (4, 7) & 0x9) == 0x9) + /* LDR immediate offset, no write-back, up, pre indexed. */ + LHPREUP (); + /* Continue with instruction decoding. */ +#endif + rhs = DPSRegRHS; + dest = LHS & ~rhs; + WRITESDEST (dest); + break; + + case 0x1e: /* MVN reg */ +#ifdef MODET + if (BITS (4, 7) == 0xB) + { + /* STRH immediate offset, write-back, up, pre indexed. */ + SHPREUPWB (); + break; + } + if (BITS (4, 7) == 0xD) + { + Handle_Load_Double (state, instr); + break; + } + if (BITS (4, 7) == 0xF) + { + Handle_Store_Double (state, instr); + break; + } +#endif + dest = ~DPRegRHS; + WRITEDEST (dest); + break; + + case 0x1f: /* MVNS reg */ +#ifdef MODET + if ((BITS (4, 7) & 0x9) == 0x9) + /* LDR immediate offset, write-back, up, pre indexed. */ + LHPREUPWB (); + /* Continue instruction decoding. */ +#endif + dest = ~DPSRegRHS; + WRITESDEST (dest); + break; + + + /* Data Processing Immediate RHS Instructions. */ + + case 0x20: /* AND immed */ + dest = LHS & DPImmRHS; + WRITEDEST (dest); + break; + + case 0x21: /* ANDS immed */ + DPSImmRHS; + dest = LHS & rhs; + WRITESDEST (dest); + break; + + case 0x22: /* EOR immed */ + dest = LHS ^ DPImmRHS; + WRITEDEST (dest); + break; + + case 0x23: /* EORS immed */ + DPSImmRHS; + dest = LHS ^ rhs; + WRITESDEST (dest); + break; + + case 0x24: /* SUB immed */ + dest = LHS - DPImmRHS; + WRITEDEST (dest); + break; + + case 0x25: /* SUBS immed */ + lhs = LHS; + rhs = DPImmRHS; + dest = lhs - rhs; + + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) + { + ARMul_SubCarry (state, lhs, rhs, dest); + ARMul_SubOverflow (state, lhs, rhs, dest); + } + else + { + CLEARC; + CLEARV; + } + WRITESDEST (dest); + break; + + case 0x26: /* RSB immed */ + dest = DPImmRHS - LHS; + WRITEDEST (dest); + break; + + case 0x27: /* RSBS immed */ + lhs = LHS; + rhs = DPImmRHS; + dest = rhs - lhs; + + if ((rhs >= lhs) || ((rhs | lhs) >> 31)) + { + ARMul_SubCarry (state, rhs, lhs, dest); + ARMul_SubOverflow (state, rhs, lhs, dest); + } + else + { + CLEARC; + CLEARV; + } + WRITESDEST (dest); + break; + + case 0x28: /* ADD immed */ + dest = LHS + DPImmRHS; + WRITEDEST (dest); + break; + + case 0x29: /* ADDS immed */ + lhs = LHS; + rhs = DPImmRHS; + dest = lhs + rhs; + ASSIGNZ (dest == 0); + + if ((lhs | rhs) >> 30) + { + /* Possible C,V,N to set. */ + ASSIGNN (NEG (dest)); + ARMul_AddCarry (state, lhs, rhs, dest); + ARMul_AddOverflow (state, lhs, rhs, dest); + } + else + { + CLEARN; + CLEARC; + CLEARV; + } + WRITESDEST (dest); + break; + + case 0x2a: /* ADC immed */ + dest = LHS + DPImmRHS + CFLAG; + WRITEDEST (dest); + break; + + case 0x2b: /* ADCS immed */ + lhs = LHS; + rhs = DPImmRHS; + dest = lhs + rhs + CFLAG; + ASSIGNZ (dest == 0); + if ((lhs | rhs) >> 30) + { + /* Possible C,V,N to set. */ + ASSIGNN (NEG (dest)); + ARMul_AddCarry (state, lhs, rhs, dest); + ARMul_AddOverflow (state, lhs, rhs, dest); + } + else + { + CLEARN; + CLEARC; + CLEARV; + } + WRITESDEST (dest); + break; + + case 0x2c: /* SBC immed */ + dest = LHS - DPImmRHS - !CFLAG; + WRITEDEST (dest); + break; + + case 0x2d: /* SBCS immed */ + lhs = LHS; + rhs = DPImmRHS; + dest = lhs - rhs - !CFLAG; + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) + { + ARMul_SubCarry (state, lhs, rhs, dest); + ARMul_SubOverflow (state, lhs, rhs, dest); + } + else + { + CLEARC; + CLEARV; + } + WRITESDEST (dest); + break; + + case 0x2e: /* RSC immed */ + dest = DPImmRHS - LHS - !CFLAG; + WRITEDEST (dest); + break; + + case 0x2f: /* RSCS immed */ + lhs = LHS; + rhs = DPImmRHS; + dest = rhs - lhs - !CFLAG; + if ((rhs >= lhs) || ((rhs | lhs) >> 31)) + { + ARMul_SubCarry (state, rhs, lhs, dest); + ARMul_SubOverflow (state, rhs, lhs, dest); + } + else + { + CLEARC; + CLEARV; + } + WRITESDEST (dest); + break; + + case 0x30: /* TST immed */ + UNDEF_Test; + break; + + case 0x31: /* TSTP immed */ + if (DESTReg == 15) + { + /* TSTP immed. */ +#ifdef MODE32 + state->Cpsr = GETSPSR (state->Bank); + ARMul_CPSRAltered (state); +#else + temp = LHS & DPImmRHS; + SETR15PSR (temp); +#endif + } + else + { + /* TST immed. */ + DPSImmRHS; + dest = LHS & rhs; + ARMul_NegZero (state, dest); + } + break; + + case 0x32: /* TEQ immed and MSR immed to CPSR */ + if (DESTReg == 15) + /* MSR immed to CPSR. */ + ARMul_FixCPSR (state, instr, DPImmRHS); + else + UNDEF_Test; + break; + + case 0x33: /* TEQP immed */ + if (DESTReg == 15) + { + /* TEQP immed. */ +#ifdef MODE32 + state->Cpsr = GETSPSR (state->Bank); + ARMul_CPSRAltered (state); +#else + temp = LHS ^ DPImmRHS; + SETR15PSR (temp); +#endif + } + else + { + DPSImmRHS; /* TEQ immed */ + dest = LHS ^ rhs; + ARMul_NegZero (state, dest); + } + break; + + case 0x34: /* CMP immed */ + UNDEF_Test; + break; + + case 0x35: /* CMPP immed */ + if (DESTReg == 15) + { + /* CMPP immed. */ +#ifdef MODE32 + state->Cpsr = GETSPSR (state->Bank); + ARMul_CPSRAltered (state); +#else + temp = LHS - DPImmRHS; + SETR15PSR (temp); +#endif + break; + } + else + { + /* CMP immed. */ + lhs = LHS; + rhs = DPImmRHS; + dest = lhs - rhs; + ARMul_NegZero (state, dest); + + if ((lhs >= rhs) || ((rhs | lhs) >> 31)) + { + ARMul_SubCarry (state, lhs, rhs, dest); + ARMul_SubOverflow (state, lhs, rhs, dest); + } + else + { + CLEARC; + CLEARV; + } + } + break; + + case 0x36: /* CMN immed and MSR immed to SPSR */ + if (DESTReg == 15) + ARMul_FixSPSR (state, instr, DPImmRHS); + else + UNDEF_Test; + break; + + case 0x37: /* CMNP immed. */ + if (DESTReg == 15) + { + /* CMNP immed. */ +#ifdef MODE32 + state->Cpsr = GETSPSR (state->Bank); + ARMul_CPSRAltered (state); +#else + temp = LHS + DPImmRHS; + SETR15PSR (temp); +#endif + break; + } + else + { + /* CMN immed. */ + lhs = LHS; + rhs = DPImmRHS; + dest = lhs + rhs; + ASSIGNZ (dest == 0); + if ((lhs | rhs) >> 30) + { + /* Possible C,V,N to set. */ + ASSIGNN (NEG (dest)); + ARMul_AddCarry (state, lhs, rhs, dest); + ARMul_AddOverflow (state, lhs, rhs, dest); + } + else + { + CLEARN; + CLEARC; + CLEARV; + } + } + break; + + case 0x38: /* ORR immed. */ + dest = LHS | DPImmRHS; + WRITEDEST (dest); + break; + + case 0x39: /* ORRS immed. */ + DPSImmRHS; + dest = LHS | rhs; + WRITESDEST (dest); + break; + + case 0x3a: /* MOV immed. */ + dest = DPImmRHS; + WRITEDEST (dest); + break; + + case 0x3b: /* MOVS immed. */ + DPSImmRHS; + WRITESDEST (rhs); + break; + + case 0x3c: /* BIC immed. */ + dest = LHS & ~DPImmRHS; + WRITEDEST (dest); + break; + + case 0x3d: /* BICS immed. */ + DPSImmRHS; + dest = LHS & ~rhs; + WRITESDEST (dest); + break; + + case 0x3e: /* MVN immed. */ + dest = ~DPImmRHS; + WRITEDEST (dest); + break; + + case 0x3f: /* MVNS immed. */ + DPSImmRHS; + WRITESDEST (~rhs); + break; + + + /* Single Data Transfer Immediate RHS Instructions. */ + + case 0x40: /* Store Word, No WriteBack, Post Dec, Immed. */ + lhs = LHS; + if (StoreWord (state, instr, lhs)) + LSBase = lhs - LSImmRHS; + break; + + case 0x41: /* Load Word, No WriteBack, Post Dec, Immed. */ + lhs = LHS; + if (LoadWord (state, instr, lhs)) + LSBase = lhs - LSImmRHS; + break; + + case 0x42: /* Store Word, WriteBack, Post Dec, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + lhs = LHS; + temp = lhs - LSImmRHS; + state->NtransSig = LOW; + if (StoreWord (state, instr, lhs)) + LSBase = temp; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x43: /* Load Word, WriteBack, Post Dec, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + lhs = LHS; + state->NtransSig = LOW; + if (LoadWord (state, instr, lhs)) + LSBase = lhs - LSImmRHS; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x44: /* Store Byte, No WriteBack, Post Dec, Immed. */ + lhs = LHS; + if (StoreByte (state, instr, lhs)) + LSBase = lhs - LSImmRHS; + break; + + case 0x45: /* Load Byte, No WriteBack, Post Dec, Immed. */ + lhs = LHS; + if (LoadByte (state, instr, lhs, LUNSIGNED)) + LSBase = lhs - LSImmRHS; + break; + + case 0x46: /* Store Byte, WriteBack, Post Dec, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + lhs = LHS; + state->NtransSig = LOW; + if (StoreByte (state, instr, lhs)) + LSBase = lhs - LSImmRHS; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x47: /* Load Byte, WriteBack, Post Dec, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + lhs = LHS; + state->NtransSig = LOW; + if (LoadByte (state, instr, lhs, LUNSIGNED)) + LSBase = lhs - LSImmRHS; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x48: /* Store Word, No WriteBack, Post Inc, Immed. */ + lhs = LHS; + if (StoreWord (state, instr, lhs)) + LSBase = lhs + LSImmRHS; + break; + + case 0x49: /* Load Word, No WriteBack, Post Inc, Immed. */ + lhs = LHS; + if (LoadWord (state, instr, lhs)) + LSBase = lhs + LSImmRHS; + break; + + case 0x4a: /* Store Word, WriteBack, Post Inc, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + lhs = LHS; + state->NtransSig = LOW; + if (StoreWord (state, instr, lhs)) + LSBase = lhs + LSImmRHS; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x4b: /* Load Word, WriteBack, Post Inc, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + lhs = LHS; + state->NtransSig = LOW; + if (LoadWord (state, instr, lhs)) + LSBase = lhs + LSImmRHS; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x4c: /* Store Byte, No WriteBack, Post Inc, Immed. */ + lhs = LHS; + if (StoreByte (state, instr, lhs)) + LSBase = lhs + LSImmRHS; + break; + + case 0x4d: /* Load Byte, No WriteBack, Post Inc, Immed. */ + lhs = LHS; + if (LoadByte (state, instr, lhs, LUNSIGNED)) + LSBase = lhs + LSImmRHS; + break; + + case 0x4e: /* Store Byte, WriteBack, Post Inc, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + lhs = LHS; + state->NtransSig = LOW; + if (StoreByte (state, instr, lhs)) + LSBase = lhs + LSImmRHS; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x4f: /* Load Byte, WriteBack, Post Inc, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + lhs = LHS; + state->NtransSig = LOW; + if (LoadByte (state, instr, lhs, LUNSIGNED)) + LSBase = lhs + LSImmRHS; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + + case 0x50: /* Store Word, No WriteBack, Pre Dec, Immed. */ + (void) StoreWord (state, instr, LHS - LSImmRHS); + break; + + case 0x51: /* Load Word, No WriteBack, Pre Dec, Immed. */ + (void) LoadWord (state, instr, LHS - LSImmRHS); + break; + + case 0x52: /* Store Word, WriteBack, Pre Dec, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + temp = LHS - LSImmRHS; + if (StoreWord (state, instr, temp)) + LSBase = temp; + break; + + case 0x53: /* Load Word, WriteBack, Pre Dec, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + temp = LHS - LSImmRHS; + if (LoadWord (state, instr, temp)) + LSBase = temp; + break; + + case 0x54: /* Store Byte, No WriteBack, Pre Dec, Immed. */ + (void) StoreByte (state, instr, LHS - LSImmRHS); + break; + + case 0x55: /* Load Byte, No WriteBack, Pre Dec, Immed. */ + (void) LoadByte (state, instr, LHS - LSImmRHS, LUNSIGNED); + break; + + case 0x56: /* Store Byte, WriteBack, Pre Dec, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + temp = LHS - LSImmRHS; + if (StoreByte (state, instr, temp)) + LSBase = temp; + break; + + case 0x57: /* Load Byte, WriteBack, Pre Dec, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + temp = LHS - LSImmRHS; + if (LoadByte (state, instr, temp, LUNSIGNED)) + LSBase = temp; + break; + + case 0x58: /* Store Word, No WriteBack, Pre Inc, Immed. */ + (void) StoreWord (state, instr, LHS + LSImmRHS); + break; + + case 0x59: /* Load Word, No WriteBack, Pre Inc, Immed. */ + (void) LoadWord (state, instr, LHS + LSImmRHS); + break; + + case 0x5a: /* Store Word, WriteBack, Pre Inc, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + temp = LHS + LSImmRHS; + if (StoreWord (state, instr, temp)) + LSBase = temp; + break; + + case 0x5b: /* Load Word, WriteBack, Pre Inc, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + temp = LHS + LSImmRHS; + if (LoadWord (state, instr, temp)) + LSBase = temp; + break; + + case 0x5c: /* Store Byte, No WriteBack, Pre Inc, Immed. */ + (void) StoreByte (state, instr, LHS + LSImmRHS); + break; + + case 0x5d: /* Load Byte, No WriteBack, Pre Inc, Immed. */ + (void) LoadByte (state, instr, LHS + LSImmRHS, LUNSIGNED); + break; + + case 0x5e: /* Store Byte, WriteBack, Pre Inc, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + temp = LHS + LSImmRHS; + if (StoreByte (state, instr, temp)) + LSBase = temp; + break; + + case 0x5f: /* Load Byte, WriteBack, Pre Inc, Immed. */ + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + temp = LHS + LSImmRHS; + if (LoadByte (state, instr, temp, LUNSIGNED)) + LSBase = temp; + break; + + + /* Single Data Transfer Register RHS Instructions. */ + + case 0x60: /* Store Word, No WriteBack, Post Dec, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + if (StoreWord (state, instr, lhs)) + LSBase = lhs - LSRegRHS; + break; + + case 0x61: /* Load Word, No WriteBack, Post Dec, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + temp = lhs - LSRegRHS; + if (LoadWord (state, instr, lhs)) + LSBase = temp; + break; + + case 0x62: /* Store Word, WriteBack, Post Dec, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + state->NtransSig = LOW; + if (StoreWord (state, instr, lhs)) + LSBase = lhs - LSRegRHS; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x63: /* Load Word, WriteBack, Post Dec, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + temp = lhs - LSRegRHS; + state->NtransSig = LOW; + if (LoadWord (state, instr, lhs)) + LSBase = temp; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x64: /* Store Byte, No WriteBack, Post Dec, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + if (StoreByte (state, instr, lhs)) + LSBase = lhs - LSRegRHS; + break; + + case 0x65: /* Load Byte, No WriteBack, Post Dec, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + temp = lhs - LSRegRHS; + if (LoadByte (state, instr, lhs, LUNSIGNED)) + LSBase = temp; + break; + + case 0x66: /* Store Byte, WriteBack, Post Dec, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + state->NtransSig = LOW; + if (StoreByte (state, instr, lhs)) + LSBase = lhs - LSRegRHS; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x67: /* Load Byte, WriteBack, Post Dec, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + temp = lhs - LSRegRHS; + state->NtransSig = LOW; + if (LoadByte (state, instr, lhs, LUNSIGNED)) + LSBase = temp; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + if (StoreWord (state, instr, lhs)) + LSBase = lhs + LSRegRHS; + break; + + case 0x69: /* Load Word, No WriteBack, Post Inc, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + temp = lhs + LSRegRHS; + if (LoadWord (state, instr, lhs)) + LSBase = temp; + break; + + case 0x6a: /* Store Word, WriteBack, Post Inc, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + state->NtransSig = LOW; + if (StoreWord (state, instr, lhs)) + LSBase = lhs + LSRegRHS; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x6b: /* Load Word, WriteBack, Post Inc, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + temp = lhs + LSRegRHS; + state->NtransSig = LOW; + if (LoadWord (state, instr, lhs)) + LSBase = temp; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x6c: /* Store Byte, No WriteBack, Post Inc, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + if (StoreByte (state, instr, lhs)) + LSBase = lhs + LSRegRHS; + break; + + case 0x6d: /* Load Byte, No WriteBack, Post Inc, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + temp = lhs + LSRegRHS; + if (LoadByte (state, instr, lhs, LUNSIGNED)) + LSBase = temp; + break; + + case 0x6e: /* Store Byte, WriteBack, Post Inc, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + state->NtransSig = LOW; + if (StoreByte (state, instr, lhs)) + LSBase = lhs + LSRegRHS; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + case 0x6f: /* Load Byte, WriteBack, Post Inc, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + lhs = LHS; + temp = lhs + LSRegRHS; + state->NtransSig = LOW; + if (LoadByte (state, instr, lhs, LUNSIGNED)) + LSBase = temp; + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + break; + + + case 0x70: /* Store Word, No WriteBack, Pre Dec, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + (void) StoreWord (state, instr, LHS - LSRegRHS); + break; + + case 0x71: /* Load Word, No WriteBack, Pre Dec, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + (void) LoadWord (state, instr, LHS - LSRegRHS); + break; + + case 0x72: /* Store Word, WriteBack, Pre Dec, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + temp = LHS - LSRegRHS; + if (StoreWord (state, instr, temp)) + LSBase = temp; + break; + + case 0x73: /* Load Word, WriteBack, Pre Dec, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + temp = LHS - LSRegRHS; + if (LoadWord (state, instr, temp)) + LSBase = temp; + break; + + case 0x74: /* Store Byte, No WriteBack, Pre Dec, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + (void) StoreByte (state, instr, LHS - LSRegRHS); + break; + + case 0x75: /* Load Byte, No WriteBack, Pre Dec, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + (void) LoadByte (state, instr, LHS - LSRegRHS, LUNSIGNED); + break; + + case 0x76: /* Store Byte, WriteBack, Pre Dec, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + temp = LHS - LSRegRHS; + if (StoreByte (state, instr, temp)) + LSBase = temp; + break; + + case 0x77: /* Load Byte, WriteBack, Pre Dec, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + temp = LHS - LSRegRHS; + if (LoadByte (state, instr, temp, LUNSIGNED)) + LSBase = temp; + break; + + case 0x78: /* Store Word, No WriteBack, Pre Inc, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + (void) StoreWord (state, instr, LHS + LSRegRHS); + break; + + case 0x79: /* Load Word, No WriteBack, Pre Inc, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + (void) LoadWord (state, instr, LHS + LSRegRHS); + break; + + case 0x7a: /* Store Word, WriteBack, Pre Inc, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + temp = LHS + LSRegRHS; + if (StoreWord (state, instr, temp)) + LSBase = temp; + break; + + case 0x7b: /* Load Word, WriteBack, Pre Inc, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + temp = LHS + LSRegRHS; + if (LoadWord (state, instr, temp)) + LSBase = temp; + break; + + case 0x7c: /* Store Byte, No WriteBack, Pre Inc, Reg. */ + if (BIT (4)) + { +#ifdef MODE32 + if (state->is_v6 + && handle_v6_insn (state, instr)) + break; +#endif + ARMul_UndefInstr (state, instr); + break; + } + (void) StoreByte (state, instr, LHS + LSRegRHS); + break; + + case 0x7d: /* Load Byte, No WriteBack, Pre Inc, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + (void) LoadByte (state, instr, LHS + LSRegRHS, LUNSIGNED); + break; + + case 0x7e: /* Store Byte, WriteBack, Pre Inc, Reg. */ + if (BIT (4)) + { + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + temp = LHS + LSRegRHS; + if (StoreByte (state, instr, temp)) + LSBase = temp; + break; + + case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg. */ + if (BIT (4)) + { + /* Check for the special breakpoint opcode. + This value should correspond to the value defined + as ARM_BE_BREAKPOINT in gdb/arm/tm-arm.h. */ + if (BITS (0, 19) == 0xfdefe) + { + if (!ARMul_OSHandleSWI (state, SWI_Breakpoint)) + ARMul_Abort (state, ARMul_SWIV); + } + else + ARMul_UndefInstr (state, instr); + break; + } + UNDEF_LSRBaseEQOffWb; + UNDEF_LSRBaseEQDestWb; + UNDEF_LSRPCBaseWb; + UNDEF_LSRPCOffWb; + temp = LHS + LSRegRHS; + if (LoadByte (state, instr, temp, LUNSIGNED)) + LSBase = temp; + break; + + + /* Multiple Data Transfer Instructions. */ + + case 0x80: /* Store, No WriteBack, Post Dec. */ + STOREMULT (instr, LSBase - LSMNumRegs + 4L, 0L); + break; + + case 0x81: /* Load, No WriteBack, Post Dec. */ + LOADMULT (instr, LSBase - LSMNumRegs + 4L, 0L); + break; + + case 0x82: /* Store, WriteBack, Post Dec. */ + temp = LSBase - LSMNumRegs; + STOREMULT (instr, temp + 4L, temp); + break; + + case 0x83: /* Load, WriteBack, Post Dec. */ + temp = LSBase - LSMNumRegs; + LOADMULT (instr, temp + 4L, temp); + break; + + case 0x84: /* Store, Flags, No WriteBack, Post Dec. */ + STORESMULT (instr, LSBase - LSMNumRegs + 4L, 0L); + break; + + case 0x85: /* Load, Flags, No WriteBack, Post Dec. */ + LOADSMULT (instr, LSBase - LSMNumRegs + 4L, 0L); + break; + + case 0x86: /* Store, Flags, WriteBack, Post Dec. */ + temp = LSBase - LSMNumRegs; + STORESMULT (instr, temp + 4L, temp); + break; + + case 0x87: /* Load, Flags, WriteBack, Post Dec. */ + temp = LSBase - LSMNumRegs; + LOADSMULT (instr, temp + 4L, temp); + break; + + case 0x88: /* Store, No WriteBack, Post Inc. */ + STOREMULT (instr, LSBase, 0L); + break; + + case 0x89: /* Load, No WriteBack, Post Inc. */ + LOADMULT (instr, LSBase, 0L); + break; + + case 0x8a: /* Store, WriteBack, Post Inc. */ + temp = LSBase; + STOREMULT (instr, temp, temp + LSMNumRegs); + break; + + case 0x8b: /* Load, WriteBack, Post Inc. */ + temp = LSBase; + LOADMULT (instr, temp, temp + LSMNumRegs); + break; + + case 0x8c: /* Store, Flags, No WriteBack, Post Inc. */ + STORESMULT (instr, LSBase, 0L); + break; + + case 0x8d: /* Load, Flags, No WriteBack, Post Inc. */ + LOADSMULT (instr, LSBase, 0L); + break; + + case 0x8e: /* Store, Flags, WriteBack, Post Inc. */ + temp = LSBase; + STORESMULT (instr, temp, temp + LSMNumRegs); + break; + + case 0x8f: /* Load, Flags, WriteBack, Post Inc. */ + temp = LSBase; + LOADSMULT (instr, temp, temp + LSMNumRegs); + break; + + case 0x90: /* Store, No WriteBack, Pre Dec. */ + STOREMULT (instr, LSBase - LSMNumRegs, 0L); + break; + + case 0x91: /* Load, No WriteBack, Pre Dec. */ + LOADMULT (instr, LSBase - LSMNumRegs, 0L); + break; + + case 0x92: /* Store, WriteBack, Pre Dec. */ + temp = LSBase - LSMNumRegs; + STOREMULT (instr, temp, temp); + break; + + case 0x93: /* Load, WriteBack, Pre Dec. */ + temp = LSBase - LSMNumRegs; + LOADMULT (instr, temp, temp); + break; + + case 0x94: /* Store, Flags, No WriteBack, Pre Dec. */ + STORESMULT (instr, LSBase - LSMNumRegs, 0L); + break; + + case 0x95: /* Load, Flags, No WriteBack, Pre Dec. */ + LOADSMULT (instr, LSBase - LSMNumRegs, 0L); + break; + + case 0x96: /* Store, Flags, WriteBack, Pre Dec. */ + temp = LSBase - LSMNumRegs; + STORESMULT (instr, temp, temp); + break; + + case 0x97: /* Load, Flags, WriteBack, Pre Dec. */ + temp = LSBase - LSMNumRegs; + LOADSMULT (instr, temp, temp); + break; + + case 0x98: /* Store, No WriteBack, Pre Inc. */ + STOREMULT (instr, LSBase + 4L, 0L); + break; + + case 0x99: /* Load, No WriteBack, Pre Inc. */ + LOADMULT (instr, LSBase + 4L, 0L); + break; + + case 0x9a: /* Store, WriteBack, Pre Inc. */ + temp = LSBase; + STOREMULT (instr, temp + 4L, temp + LSMNumRegs); + break; + + case 0x9b: /* Load, WriteBack, Pre Inc. */ + temp = LSBase; + LOADMULT (instr, temp + 4L, temp + LSMNumRegs); + break; + + case 0x9c: /* Store, Flags, No WriteBack, Pre Inc. */ + STORESMULT (instr, LSBase + 4L, 0L); + break; + + case 0x9d: /* Load, Flags, No WriteBack, Pre Inc. */ + LOADSMULT (instr, LSBase + 4L, 0L); + break; + + case 0x9e: /* Store, Flags, WriteBack, Pre Inc. */ + temp = LSBase; + STORESMULT (instr, temp + 4L, temp + LSMNumRegs); + break; + + case 0x9f: /* Load, Flags, WriteBack, Pre Inc. */ + temp = LSBase; + LOADSMULT (instr, temp + 4L, temp + LSMNumRegs); + break; + + + /* Branch forward. */ + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + state->Reg[15] = pc + 8 + POSBRANCH; + FLUSHPIPE; + break; + + + /* Branch backward. */ + case 0xa8: + case 0xa9: + case 0xaa: + case 0xab: + case 0xac: + case 0xad: + case 0xae: + case 0xaf: + state->Reg[15] = pc + 8 + NEGBRANCH; + FLUSHPIPE; + break; + + + /* Branch and Link forward. */ + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + /* Put PC into Link. */ +#ifdef MODE32 + state->Reg[14] = pc + 4; +#else + state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE; +#endif + state->Reg[15] = pc + 8 + POSBRANCH; + FLUSHPIPE; + break; + + + /* Branch and Link backward. */ + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + /* Put PC into Link. */ +#ifdef MODE32 + state->Reg[14] = pc + 4; +#else + state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE; +#endif + state->Reg[15] = pc + 8 + NEGBRANCH; + FLUSHPIPE; + break; + + + /* Co-Processor Data Transfers. */ + case 0xc4: + if (state->is_v5) + { + /* Reading from R15 is UNPREDICTABLE. */ + if (BITS (12, 15) == 15 || BITS (16, 19) == 15) + ARMul_UndefInstr (state, instr); + /* Is access to coprocessor 0 allowed ? */ + else if (! CP_ACCESS_ALLOWED (state, CPNum)) + ARMul_UndefInstr (state, instr); + /* Special treatment for XScale coprocessors. */ + else if (state->is_XScale) + { + /* Only opcode 0 is supported. */ + if (BITS (4, 7) != 0x00) + ARMul_UndefInstr (state, instr); + /* Only coporcessor 0 is supported. */ + else if (CPNum != 0x00) + ARMul_UndefInstr (state, instr); + /* Only accumulator 0 is supported. */ + else if (BITS (0, 3) != 0x00) + ARMul_UndefInstr (state, instr); + else + { + /* XScale MAR insn. Move two registers into accumulator. */ + state->Accumulator = state->Reg[BITS (12, 15)]; + state->Accumulator += (ARMdword) state->Reg[BITS (16, 19)] << 32; + } + } + else + /* FIXME: Not sure what to do for other v5 processors. */ + ARMul_UndefInstr (state, instr); + break; + } + /* Drop through. */ + + case 0xc0: /* Store , No WriteBack , Post Dec. */ + ARMul_STC (state, instr, LHS); + break; + + case 0xc5: + if (state->is_v5) + { + /* Writes to R15 are UNPREDICATABLE. */ + if (DESTReg == 15 || LHSReg == 15) + ARMul_UndefInstr (state, instr); + /* Is access to the coprocessor allowed ? */ + else if (! CP_ACCESS_ALLOWED (state, CPNum)) + ARMul_UndefInstr (state, instr); + /* Special handling for XScale coprcoessors. */ + else if (state->is_XScale) + { + /* Only opcode 0 is supported. */ + if (BITS (4, 7) != 0x00) + ARMul_UndefInstr (state, instr); + /* Only coprocessor 0 is supported. */ + else if (CPNum != 0x00) + ARMul_UndefInstr (state, instr); + /* Only accumulator 0 is supported. */ + else if (BITS (0, 3) != 0x00) + ARMul_UndefInstr (state, instr); + else + { + /* XScale MRA insn. Move accumulator into two registers. */ + ARMword t1 = (state->Accumulator >> 32) & 255; + + if (t1 & 128) + t1 -= 256; + + state->Reg[BITS (12, 15)] = state->Accumulator; + state->Reg[BITS (16, 19)] = t1; + break; + } + } + else + /* FIXME: Not sure what to do for other v5 processors. */ + ARMul_UndefInstr (state, instr); + break; + } + /* Drop through. */ + + case 0xc1: /* Load , No WriteBack , Post Dec. */ + ARMul_LDC (state, instr, LHS); + break; + + case 0xc2: + case 0xc6: /* Store , WriteBack , Post Dec. */ + lhs = LHS; + state->Base = lhs - LSCOff; + ARMul_STC (state, instr, lhs); + break; + + case 0xc3: + case 0xc7: /* Load , WriteBack , Post Dec. */ + lhs = LHS; + state->Base = lhs - LSCOff; + ARMul_LDC (state, instr, lhs); + break; + + case 0xc8: + case 0xcc: /* Store , No WriteBack , Post Inc. */ + ARMul_STC (state, instr, LHS); + break; + + case 0xc9: + case 0xcd: /* Load , No WriteBack , Post Inc. */ + ARMul_LDC (state, instr, LHS); + break; + + case 0xca: + case 0xce: /* Store , WriteBack , Post Inc. */ + lhs = LHS; + state->Base = lhs + LSCOff; + ARMul_STC (state, instr, LHS); + break; + + case 0xcb: + case 0xcf: /* Load , WriteBack , Post Inc. */ + lhs = LHS; + state->Base = lhs + LSCOff; + ARMul_LDC (state, instr, LHS); + break; + + case 0xd0: + case 0xd4: /* Store , No WriteBack , Pre Dec. */ + ARMul_STC (state, instr, LHS - LSCOff); + break; + + case 0xd1: + case 0xd5: /* Load , No WriteBack , Pre Dec. */ + ARMul_LDC (state, instr, LHS - LSCOff); + break; + + case 0xd2: + case 0xd6: /* Store , WriteBack , Pre Dec. */ + lhs = LHS - LSCOff; + state->Base = lhs; + ARMul_STC (state, instr, lhs); + break; + + case 0xd3: + case 0xd7: /* Load , WriteBack , Pre Dec. */ + lhs = LHS - LSCOff; + state->Base = lhs; + ARMul_LDC (state, instr, lhs); + break; + + case 0xd8: + case 0xdc: /* Store , No WriteBack , Pre Inc. */ + ARMul_STC (state, instr, LHS + LSCOff); + break; + + case 0xd9: + case 0xdd: /* Load , No WriteBack , Pre Inc. */ + ARMul_LDC (state, instr, LHS + LSCOff); + break; + + case 0xda: + case 0xde: /* Store , WriteBack , Pre Inc. */ + lhs = LHS + LSCOff; + state->Base = lhs; + ARMul_STC (state, instr, lhs); + break; + + case 0xdb: + case 0xdf: /* Load , WriteBack , Pre Inc. */ + lhs = LHS + LSCOff; + state->Base = lhs; + ARMul_LDC (state, instr, lhs); + break; + + + /* Co-Processor Register Transfers (MCR) and Data Ops. */ + + case 0xe2: + if (! CP_ACCESS_ALLOWED (state, CPNum)) + { + ARMul_UndefInstr (state, instr); + break; + } + if (state->is_XScale) + switch (BITS (18, 19)) + { + case 0x0: + if (BITS (4, 11) == 1 && BITS (16, 17) == 0) + { + /* XScale MIA instruction. Signed multiplication of + two 32 bit values and addition to 40 bit accumulator. */ + ARMsdword Rm = state->Reg[MULLHSReg]; + ARMsdword Rs = state->Reg[MULACCReg]; + + if (Rm & (1 << 31)) + Rm -= 1ULL << 32; + if (Rs & (1 << 31)) + Rs -= 1ULL << 32; + state->Accumulator += Rm * Rs; + goto donext; + } + break; + + case 0x2: + if (BITS (4, 11) == 1 && BITS (16, 17) == 0) + { + /* XScale MIAPH instruction. */ + ARMword t1 = state->Reg[MULLHSReg] >> 16; + ARMword t2 = state->Reg[MULACCReg] >> 16; + ARMword t3 = state->Reg[MULLHSReg] & 0xffff; + ARMword t4 = state->Reg[MULACCReg] & 0xffff; + ARMsdword t5; + + if (t1 & (1 << 15)) + t1 -= 1 << 16; + if (t2 & (1 << 15)) + t2 -= 1 << 16; + if (t3 & (1 << 15)) + t3 -= 1 << 16; + if (t4 & (1 << 15)) + t4 -= 1 << 16; + t1 *= t2; + t5 = t1; + if (t5 & (1 << 31)) + t5 -= 1ULL << 32; + state->Accumulator += t5; + t3 *= t4; + t5 = t3; + if (t5 & (1 << 31)) + t5 -= 1ULL << 32; + state->Accumulator += t5; + goto donext; + } + break; + + case 0x3: + if (BITS (4, 11) == 1) + { + /* XScale MIAxy instruction. */ + ARMword t1; + ARMword t2; + ARMsdword t5; + + if (BIT (17)) + t1 = state->Reg[MULLHSReg] >> 16; + else + t1 = state->Reg[MULLHSReg] & 0xffff; + + if (BIT (16)) + t2 = state->Reg[MULACCReg] >> 16; + else + t2 = state->Reg[MULACCReg] & 0xffff; + + if (t1 & (1 << 15)) + t1 -= 1 << 16; + if (t2 & (1 << 15)) + t2 -= 1 << 16; + t1 *= t2; + t5 = t1; + if (t5 & (1 << 31)) + t5 -= 1ULL << 32; + state->Accumulator += t5; + goto donext; + } + break; + + default: + break; + } + /* Drop through. */ + + case 0xe0: + case 0xe4: + case 0xe6: + case 0xe8: + case 0xea: + case 0xec: + case 0xee: + if (BIT (4)) + { + /* MCR. */ + if (DESTReg == 15) + { + UNDEF_MCRPC; +#ifdef MODE32 + ARMul_MCR (state, instr, state->Reg[15] + isize); +#else + ARMul_MCR (state, instr, ECC | ER15INT | EMODE | + ((state->Reg[15] + isize) & R15PCBITS)); +#endif + } + else + ARMul_MCR (state, instr, DEST); + } + else + /* CDP Part 1. */ + ARMul_CDP (state, instr); + break; + + + /* Co-Processor Register Transfers (MRC) and Data Ops. */ + case 0xe1: + case 0xe3: + case 0xe5: + case 0xe7: + case 0xe9: + case 0xeb: + case 0xed: + case 0xef: + if (BIT (4)) + { + /* MRC */ + temp = ARMul_MRC (state, instr); + if (DESTReg == 15) + { + ASSIGNN ((temp & NBIT) != 0); + ASSIGNZ ((temp & ZBIT) != 0); + ASSIGNC ((temp & CBIT) != 0); + ASSIGNV ((temp & VBIT) != 0); + } + else + DEST = temp; + } + else + /* CDP Part 2. */ + ARMul_CDP (state, instr); + break; + + + /* SWI instruction. */ + case 0xf0: + case 0xf1: + case 0xf2: + case 0xf3: + case 0xf4: + case 0xf5: + case 0xf6: + case 0xf7: + case 0xf8: + case 0xf9: + case 0xfa: + case 0xfb: + case 0xfc: + case 0xfd: + case 0xfe: + case 0xff: + if (instr == ARMul_ABORTWORD && state->AbortAddr == pc) + { + /* A prefetch abort. */ + XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc); + ARMul_Abort (state, ARMul_PrefetchAbortV); + break; + } + + if (!ARMul_OSHandleSWI (state, BITS (0, 23))) + ARMul_Abort (state, ARMul_SWIV); + + break; + } + } + +#ifdef MODET + donext: +#endif + +#ifdef NEED_UI_LOOP_HOOK + if (deprecated_ui_loop_hook != NULL && ui_loop_hook_counter-- < 0) + { + ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL; + deprecated_ui_loop_hook (0); + } +#endif /* NEED_UI_LOOP_HOOK */ + + if (state->Emulate == ONCE) + state->Emulate = STOP; + /* If we have changed mode, allow the PC to advance before stopping. */ + else if (state->Emulate == CHANGEMODE) + continue; + else if (state->Emulate != RUN) + break; + } + while (!stop_simulator); + + state->decoded = decoded; + state->loaded = loaded; + state->pc = pc; + + return pc; +} + +/* This routine evaluates most Data Processing register RHS's with the S + bit clear. It is intended to be called from the macro DPRegRHS, which + filters the common case of an unshifted register with in line code. */ + +static ARMword +GetDPRegRHS (ARMul_State * state, ARMword instr) +{ + ARMword shamt, base; + + base = RHSReg; + if (BIT (4)) + { + /* Shift amount in a register. */ + UNDEF_Shift; + INCPC; +#ifndef MODE32 + if (base == 15) + base = ECC | ER15INT | R15PC | EMODE; + else +#endif + base = state->Reg[base]; + ARMul_Icycles (state, 1, 0L); + shamt = state->Reg[BITS (8, 11)] & 0xff; + switch ((int) BITS (5, 6)) + { + case LSL: + if (shamt == 0) + return (base); + else if (shamt >= 32) + return (0); + else + return (base << shamt); + case LSR: + if (shamt == 0) + return (base); + else if (shamt >= 32) + return (0); + else + return (base >> shamt); + case ASR: + if (shamt == 0) + return (base); + else if (shamt >= 32) + return ((ARMword) ((ARMsword) base >> 31L)); + else + return ((ARMword) ((ARMsword) base >> (int) shamt)); + case ROR: + shamt &= 0x1f; + if (shamt == 0) + return (base); + else + return ((base << (32 - shamt)) | (base >> shamt)); + } + } + else + { + /* Shift amount is a constant. */ +#ifndef MODE32 + if (base == 15) + base = ECC | ER15INT | R15PC | EMODE; + else +#endif + base = state->Reg[base]; + shamt = BITS (7, 11); + switch ((int) BITS (5, 6)) + { + case LSL: + return (base << shamt); + case LSR: + if (shamt == 0) + return (0); + else + return (base >> shamt); + case ASR: + if (shamt == 0) + return ((ARMword) ((ARMsword) base >> 31L)); + else + return ((ARMword) ((ARMsword) base >> (int) shamt)); + case ROR: + if (shamt == 0) + /* It's an RRX. */ + return ((base >> 1) | (CFLAG << 31)); + else + return ((base << (32 - shamt)) | (base >> shamt)); + } + } + + return 0; +} + +/* This routine evaluates most Logical Data Processing register RHS's + with the S bit set. It is intended to be called from the macro + DPSRegRHS, which filters the common case of an unshifted register + with in line code. */ + +static ARMword +GetDPSRegRHS (ARMul_State * state, ARMword instr) +{ + ARMword shamt, base; + + base = RHSReg; + if (BIT (4)) + { + /* Shift amount in a register. */ + UNDEF_Shift; + INCPC; +#ifndef MODE32 + if (base == 15) + base = ECC | ER15INT | R15PC | EMODE; + else +#endif + base = state->Reg[base]; + ARMul_Icycles (state, 1, 0L); + shamt = state->Reg[BITS (8, 11)] & 0xff; + switch ((int) BITS (5, 6)) + { + case LSL: + if (shamt == 0) + return (base); + else if (shamt == 32) + { + ASSIGNC (base & 1); + return (0); + } + else if (shamt > 32) + { + CLEARC; + return (0); + } + else + { + ASSIGNC ((base >> (32 - shamt)) & 1); + return (base << shamt); + } + case LSR: + if (shamt == 0) + return (base); + else if (shamt == 32) + { + ASSIGNC (base >> 31); + return (0); + } + else if (shamt > 32) + { + CLEARC; + return (0); + } + else + { + ASSIGNC ((base >> (shamt - 1)) & 1); + return (base >> shamt); + } + case ASR: + if (shamt == 0) + return (base); + else if (shamt >= 32) + { + ASSIGNC (base >> 31L); + return ((ARMword) ((ARMsword) base >> 31L)); + } + else + { + ASSIGNC ((ARMword) ((ARMsword) base >> (int) (shamt - 1)) & 1); + return ((ARMword) ((ARMsword) base >> (int) shamt)); + } + case ROR: + if (shamt == 0) + return (base); + shamt &= 0x1f; + if (shamt == 0) + { + ASSIGNC (base >> 31); + return (base); + } + else + { + ASSIGNC ((base >> (shamt - 1)) & 1); + return ((base << (32 - shamt)) | (base >> shamt)); + } + } + } + else + { + /* Shift amount is a constant. */ +#ifndef MODE32 + if (base == 15) + base = ECC | ER15INT | R15PC | EMODE; + else +#endif + base = state->Reg[base]; + shamt = BITS (7, 11); + + switch ((int) BITS (5, 6)) + { + case LSL: + ASSIGNC ((base >> (32 - shamt)) & 1); + return (base << shamt); + case LSR: + if (shamt == 0) + { + ASSIGNC (base >> 31); + return (0); + } + else + { + ASSIGNC ((base >> (shamt - 1)) & 1); + return (base >> shamt); + } + case ASR: + if (shamt == 0) + { + ASSIGNC (base >> 31L); + return ((ARMword) ((ARMsword) base >> 31L)); + } + else + { + ASSIGNC ((ARMword) ((ARMsword) base >> (int) (shamt - 1)) & 1); + return ((ARMword) ((ARMsword) base >> (int) shamt)); + } + case ROR: + if (shamt == 0) + { + /* It's an RRX. */ + shamt = CFLAG; + ASSIGNC (base & 1); + return ((base >> 1) | (shamt << 31)); + } + else + { + ASSIGNC ((base >> (shamt - 1)) & 1); + return ((base << (32 - shamt)) | (base >> shamt)); + } + } + } + + return 0; +} + +/* This routine handles writes to register 15 when the S bit is not set. */ + +static void +WriteR15 (ARMul_State * state, ARMword src) +{ + /* The ARM documentation states that the two least significant bits + are discarded when setting PC, except in the cases handled by + WriteR15Branch() below. It's probably an oversight: in THUMB + mode, the second least significant bit should probably not be + discarded. */ +#ifdef MODET + if (TFLAG) + src &= 0xfffffffe; + else +#endif + src &= 0xfffffffc; + +#ifdef MODE32 + state->Reg[15] = src & PCBITS; +#else + state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE; + ARMul_R15Altered (state); +#endif + + FLUSHPIPE; +} + +/* This routine handles writes to register 15 when the S bit is set. */ + +static void +WriteSR15 (ARMul_State * state, ARMword src) +{ +#ifdef MODE32 + if (state->Bank > 0) + { + state->Cpsr = state->Spsr[state->Bank]; + ARMul_CPSRAltered (state); + } +#ifdef MODET + if (TFLAG) + src &= 0xfffffffe; + else +#endif + src &= 0xfffffffc; + state->Reg[15] = src & PCBITS; +#else +#ifdef MODET + if (TFLAG) + /* ARMul_R15Altered would have to support it. */ + abort (); + else +#endif + src &= 0xfffffffc; + + if (state->Bank == USERBANK) + state->Reg[15] = (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE; + else + state->Reg[15] = src; + + ARMul_R15Altered (state); +#endif + FLUSHPIPE; +} + +/* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM + will switch to Thumb mode if the least significant bit is set. */ + +static void +WriteR15Branch (ARMul_State * state, ARMword src) +{ +#ifdef MODET + if (src & 1) + { + /* Thumb bit. */ + SETT; + state->Reg[15] = src & 0xfffffffe; + } + else + { + CLEART; + state->Reg[15] = src & 0xfffffffc; + } + FLUSHPIPE; +#else + WriteR15 (state, src); +#endif +} + +/* This routine evaluates most Load and Store register RHS's. It is + intended to be called from the macro LSRegRHS, which filters the + common case of an unshifted register with in line code. */ + +static ARMword +GetLSRegRHS (ARMul_State * state, ARMword instr) +{ + ARMword shamt, base; + + base = RHSReg; +#ifndef MODE32 + if (base == 15) + /* Now forbidden, but ... */ + base = ECC | ER15INT | R15PC | EMODE; + else +#endif + base = state->Reg[base]; + + shamt = BITS (7, 11); + switch ((int) BITS (5, 6)) + { + case LSL: + return (base << shamt); + case LSR: + if (shamt == 0) + return (0); + else + return (base >> shamt); + case ASR: + if (shamt == 0) + return ((ARMword) ((ARMsword) base >> 31L)); + else + return ((ARMword) ((ARMsword) base >> (int) shamt)); + case ROR: + if (shamt == 0) + /* It's an RRX. */ + return ((base >> 1) | (CFLAG << 31)); + else + return ((base << (32 - shamt)) | (base >> shamt)); + default: + break; + } + return 0; +} + +/* This routine evaluates the ARM7T halfword and signed transfer RHS's. */ + +static ARMword +GetLS7RHS (ARMul_State * state, ARMword instr) +{ + if (BIT (22) == 0) + { + /* Register. */ +#ifndef MODE32 + if (RHSReg == 15) + /* Now forbidden, but ... */ + return ECC | ER15INT | R15PC | EMODE; +#endif + return state->Reg[RHSReg]; + } + + /* Immediate. */ + return BITS (0, 3) | (BITS (8, 11) << 4); +} + +/* This function does the work of loading a word for a LDR instruction. */ + +static unsigned +LoadWord (ARMul_State * state, ARMword instr, ARMword address) +{ + ARMword dest; + + BUSUSEDINCPCS; +#ifndef MODE32 + if (ADDREXCEPT (address)) + INTERNALABORT (address); +#endif + + dest = ARMul_LoadWordN (state, address); + + if (state->Aborted) + { + TAKEABORT; + return state->lateabtSig; + } + if (address & 3) + dest = ARMul_Align (state, address, dest); + WRITEDESTB (dest); + ARMul_Icycles (state, 1, 0L); + + return (DESTReg != LHSReg); +} + +#ifdef MODET +/* This function does the work of loading a halfword. */ + +static unsigned +LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address, + int signextend) +{ + ARMword dest; + + BUSUSEDINCPCS; +#ifndef MODE32 + if (ADDREXCEPT (address)) + INTERNALABORT (address); +#endif + dest = ARMul_LoadHalfWord (state, address); + if (state->Aborted) + { + TAKEABORT; + return state->lateabtSig; + } + UNDEF_LSRBPC; + if (signextend) + if (dest & 1 << (16 - 1)) + dest = (dest & ((1 << 16) - 1)) - (1 << 16); + + WRITEDEST (dest); + ARMul_Icycles (state, 1, 0L); + return (DESTReg != LHSReg); +} + +#endif /* MODET */ + +/* This function does the work of loading a byte for a LDRB instruction. */ + +static unsigned +LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend) +{ + ARMword dest; + + BUSUSEDINCPCS; +#ifndef MODE32 + if (ADDREXCEPT (address)) + INTERNALABORT (address); +#endif + dest = ARMul_LoadByte (state, address); + if (state->Aborted) + { + TAKEABORT; + return state->lateabtSig; + } + UNDEF_LSRBPC; + if (signextend) + if (dest & 1 << (8 - 1)) + dest = (dest & ((1 << 8) - 1)) - (1 << 8); + + WRITEDEST (dest); + ARMul_Icycles (state, 1, 0L); + + return (DESTReg != LHSReg); +} + +/* This function does the work of loading two words for a LDRD instruction. */ + +static void +Handle_Load_Double (ARMul_State * state, ARMword instr) +{ + ARMword dest_reg; + ARMword addr_reg; + ARMword write_back = BIT (21); + ARMword immediate = BIT (22); + ARMword add_to_base = BIT (23); + ARMword pre_indexed = BIT (24); + ARMword offset; + ARMword addr; + ARMword sum; + ARMword base; + ARMword value1; + ARMword value2; + + BUSUSEDINCPCS; + + /* If the writeback bit is set, the pre-index bit must be clear. */ + if (write_back && ! pre_indexed) + { + ARMul_UndefInstr (state, instr); + return; + } + + /* Extract the base address register. */ + addr_reg = LHSReg; + + /* Extract the destination register and check it. */ + dest_reg = DESTReg; + + /* Destination register must be even. */ + if ((dest_reg & 1) + /* Destination register cannot be LR. */ + || (dest_reg == 14)) + { + ARMul_UndefInstr (state, instr); + return; + } + + /* Compute the base address. */ + base = state->Reg[addr_reg]; + + /* Compute the offset. */ + offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg]; + + /* Compute the sum of the two. */ + if (add_to_base) + sum = base + offset; + else + sum = base - offset; + + /* If this is a pre-indexed mode use the sum. */ + if (pre_indexed) + addr = sum; + else + addr = base; + + /* The address must be aligned on a 8 byte boundary. */ + if (addr & 0x7) + { +#ifdef ABORTS + ARMul_DATAABORT (addr); +#else + ARMul_UndefInstr (state, instr); +#endif + return; + } + + /* For pre indexed or post indexed addressing modes, + check that the destination registers do not overlap + the address registers. */ + if ((! pre_indexed || write_back) + && ( addr_reg == dest_reg + || addr_reg == dest_reg + 1)) + { + ARMul_UndefInstr (state, instr); + return; + } + + /* Load the words. */ + value1 = ARMul_LoadWordN (state, addr); + value2 = ARMul_LoadWordN (state, addr + 4); + + /* Check for data aborts. */ + if (state->Aborted) + { + TAKEABORT; + return; + } + + ARMul_Icycles (state, 2, 0L); + + /* Store the values. */ + state->Reg[dest_reg] = value1; + state->Reg[dest_reg + 1] = value2; + + /* Do the post addressing and writeback. */ + if (! pre_indexed) + addr = sum; + + if (! pre_indexed || write_back) + state->Reg[addr_reg] = addr; +} + +/* This function does the work of storing two words for a STRD instruction. */ + +static void +Handle_Store_Double (ARMul_State * state, ARMword instr) +{ + ARMword src_reg; + ARMword addr_reg; + ARMword write_back = BIT (21); + ARMword immediate = BIT (22); + ARMword add_to_base = BIT (23); + ARMword pre_indexed = BIT (24); + ARMword offset; + ARMword addr; + ARMword sum; + ARMword base; + + BUSUSEDINCPCS; + + /* If the writeback bit is set, the pre-index bit must be clear. */ + if (write_back && ! pre_indexed) + { + ARMul_UndefInstr (state, instr); + return; + } + + /* Extract the base address register. */ + addr_reg = LHSReg; + + /* Base register cannot be PC. */ + if (addr_reg == 15) + { + ARMul_UndefInstr (state, instr); + return; + } + + /* Extract the source register. */ + src_reg = DESTReg; + + /* Source register must be even. */ + if (src_reg & 1) + { + ARMul_UndefInstr (state, instr); + return; + } + + /* Compute the base address. */ + base = state->Reg[addr_reg]; + + /* Compute the offset. */ + offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg]; + + /* Compute the sum of the two. */ + if (add_to_base) + sum = base + offset; + else + sum = base - offset; + + /* If this is a pre-indexed mode use the sum. */ + if (pre_indexed) + addr = sum; + else + addr = base; + + /* The address must be aligned on a 8 byte boundary. */ + if (addr & 0x7) + { +#ifdef ABORTS + ARMul_DATAABORT (addr); +#else + ARMul_UndefInstr (state, instr); +#endif + return; + } + + /* For pre indexed or post indexed addressing modes, + check that the destination registers do not overlap + the address registers. */ + if ((! pre_indexed || write_back) + && ( addr_reg == src_reg + || addr_reg == src_reg + 1)) + { + ARMul_UndefInstr (state, instr); + return; + } + + /* Load the words. */ + ARMul_StoreWordN (state, addr, state->Reg[src_reg]); + ARMul_StoreWordN (state, addr + 4, state->Reg[src_reg + 1]); + + if (state->Aborted) + { + TAKEABORT; + return; + } + + /* Do the post addressing and writeback. */ + if (! pre_indexed) + addr = sum; + + if (! pre_indexed || write_back) + state->Reg[addr_reg] = addr; +} + +/* This function does the work of storing a word from a STR instruction. */ + +static unsigned +StoreWord (ARMul_State * state, ARMword instr, ARMword address) +{ + BUSUSEDINCPCN; +#ifndef MODE32 + if (DESTReg == 15) + state->Reg[15] = ECC | ER15INT | R15PC | EMODE; +#endif +#ifdef MODE32 + ARMul_StoreWordN (state, address, DEST); +#else + if (VECTORACCESS (address) || ADDREXCEPT (address)) + { + INTERNALABORT (address); + (void) ARMul_LoadWordN (state, address); + } + else + ARMul_StoreWordN (state, address, DEST); +#endif + if (state->Aborted) + { + TAKEABORT; + return state->lateabtSig; + } + return TRUE; +} + +#ifdef MODET +/* This function does the work of storing a byte for a STRH instruction. */ + +static unsigned +StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address) +{ + BUSUSEDINCPCN; + +#ifndef MODE32 + if (DESTReg == 15) + state->Reg[15] = ECC | ER15INT | R15PC | EMODE; +#endif + +#ifdef MODE32 + ARMul_StoreHalfWord (state, address, DEST); +#else + if (VECTORACCESS (address) || ADDREXCEPT (address)) + { + INTERNALABORT (address); + (void) ARMul_LoadHalfWord (state, address); + } + else + ARMul_StoreHalfWord (state, address, DEST); +#endif + + if (state->Aborted) + { + TAKEABORT; + return state->lateabtSig; + } + return TRUE; +} + +#endif /* MODET */ + +/* This function does the work of storing a byte for a STRB instruction. */ + +static unsigned +StoreByte (ARMul_State * state, ARMword instr, ARMword address) +{ + BUSUSEDINCPCN; +#ifndef MODE32 + if (DESTReg == 15) + state->Reg[15] = ECC | ER15INT | R15PC | EMODE; +#endif +#ifdef MODE32 + ARMul_StoreByte (state, address, DEST); +#else + if (VECTORACCESS (address) || ADDREXCEPT (address)) + { + INTERNALABORT (address); + (void) ARMul_LoadByte (state, address); + } + else + ARMul_StoreByte (state, address, DEST); +#endif + if (state->Aborted) + { + TAKEABORT; + return state->lateabtSig; + } + UNDEF_LSRBPC; + return TRUE; +} + +/* This function does the work of loading the registers listed in an LDM + instruction, when the S bit is clear. The code here is always increment + after, it's up to the caller to get the input address correct and to + handle base register modification. */ + +static void +LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase) +{ + ARMword dest, temp; + + UNDEF_LSMNoRegs; + UNDEF_LSMPCBase; + UNDEF_LSMBaseInListWb; + BUSUSEDINCPCS; +#ifndef MODE32 + if (ADDREXCEPT (address)) + INTERNALABORT (address); +#endif + if (BIT (21) && LHSReg != 15) + LSBase = WBBase; + + /* N cycle first. */ + for (temp = 0; !BIT (temp); temp++) + ; + + dest = ARMul_LoadWordN (state, address); + + if (!state->abortSig && !state->Aborted) + state->Reg[temp++] = dest; + else if (!state->Aborted) + { + XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); + state->Aborted = ARMul_DataAbortV; + } + + /* S cycles from here on. */ + for (; temp < 16; temp ++) + if (BIT (temp)) + { + /* Load this register. */ + address += 4; + dest = ARMul_LoadWordS (state, address); + + if (!state->abortSig && !state->Aborted) + state->Reg[temp] = dest; + else if (!state->Aborted) + { + XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); + state->Aborted = ARMul_DataAbortV; + } + } + + if (BIT (15) && !state->Aborted) + /* PC is in the reg list. */ + WriteR15Branch (state, PC); + + /* To write back the final register. */ + ARMul_Icycles (state, 1, 0L); + + if (state->Aborted) + { + if (BIT (21) && LHSReg != 15) + LSBase = WBBase; + TAKEABORT; + } +} + +/* This function does the work of loading the registers listed in an LDM + instruction, when the S bit is set. The code here is always increment + after, it's up to the caller to get the input address correct and to + handle base register modification. */ + +static void +LoadSMult (ARMul_State * state, + ARMword instr, + ARMword address, + ARMword WBBase) +{ + ARMword dest, temp; + + UNDEF_LSMNoRegs; + UNDEF_LSMPCBase; + UNDEF_LSMBaseInListWb; + + BUSUSEDINCPCS; + +#ifndef MODE32 + if (ADDREXCEPT (address)) + INTERNALABORT (address); +#endif + + if (BIT (21) && LHSReg != 15) + LSBase = WBBase; + + if (!BIT (15) && state->Bank != USERBANK) + { + /* Temporary reg bank switch. */ + (void) ARMul_SwitchMode (state, state->Mode, USER26MODE); + UNDEF_LSMUserBankWb; + } + + /* N cycle first. */ + for (temp = 0; !BIT (temp); temp ++) + ; + + dest = ARMul_LoadWordN (state, address); + + if (!state->abortSig) + state->Reg[temp++] = dest; + else if (!state->Aborted) + { + XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); + state->Aborted = ARMul_DataAbortV; + } + + /* S cycles from here on. */ + for (; temp < 16; temp++) + if (BIT (temp)) + { + /* Load this register. */ + address += 4; + dest = ARMul_LoadWordS (state, address); + + if (!state->abortSig && !state->Aborted) + state->Reg[temp] = dest; + else if (!state->Aborted) + { + XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); + state->Aborted = ARMul_DataAbortV; + } + } + + if (BIT (15) && !state->Aborted) + { + /* PC is in the reg list. */ +#ifdef MODE32 + if (state->Mode != USER26MODE && state->Mode != USER32MODE) + { + state->Cpsr = GETSPSR (state->Bank); + ARMul_CPSRAltered (state); + } + + WriteR15 (state, PC); +#else + if (state->Mode == USER26MODE || state->Mode == USER32MODE) + { + /* Protect bits in user mode. */ + ASSIGNN ((state->Reg[15] & NBIT) != 0); + ASSIGNZ ((state->Reg[15] & ZBIT) != 0); + ASSIGNC ((state->Reg[15] & CBIT) != 0); + ASSIGNV ((state->Reg[15] & VBIT) != 0); + } + else + ARMul_R15Altered (state); + + FLUSHPIPE; +#endif + } + + if (!BIT (15) && state->Mode != USER26MODE && state->Mode != USER32MODE) + /* Restore the correct bank. */ + (void) ARMul_SwitchMode (state, USER26MODE, state->Mode); + + /* To write back the final register. */ + ARMul_Icycles (state, 1, 0L); + + if (state->Aborted) + { + if (BIT (21) && LHSReg != 15) + LSBase = WBBase; + + TAKEABORT; + } +} + +/* This function does the work of storing the registers listed in an STM + instruction, when the S bit is clear. The code here is always increment + after, it's up to the caller to get the input address correct and to + handle base register modification. */ + +static void +StoreMult (ARMul_State * state, + ARMword instr, + ARMword address, + ARMword WBBase) +{ + ARMword temp; + + UNDEF_LSMNoRegs; + UNDEF_LSMPCBase; + UNDEF_LSMBaseInListWb; + + if (!TFLAG) + /* N-cycle, increment the PC and update the NextInstr state. */ + BUSUSEDINCPCN; + +#ifndef MODE32 + if (VECTORACCESS (address) || ADDREXCEPT (address)) + INTERNALABORT (address); + + if (BIT (15)) + PATCHR15; +#endif + + /* N cycle first. */ + for (temp = 0; !BIT (temp); temp ++) + ; + +#ifdef MODE32 + ARMul_StoreWordN (state, address, state->Reg[temp++]); +#else + if (state->Aborted) + { + (void) ARMul_LoadWordN (state, address); + + /* Fake the Stores as Loads. */ + for (; temp < 16; temp++) + if (BIT (temp)) + { + /* Save this register. */ + address += 4; + (void) ARMul_LoadWordS (state, address); + } + + if (BIT (21) && LHSReg != 15) + LSBase = WBBase; + TAKEABORT; + return; + } + else + ARMul_StoreWordN (state, address, state->Reg[temp++]); +#endif + + if (state->abortSig && !state->Aborted) + { + XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); + state->Aborted = ARMul_DataAbortV; + } + + if (BIT (21) && LHSReg != 15) + LSBase = WBBase; + + /* S cycles from here on. */ + for (; temp < 16; temp ++) + if (BIT (temp)) + { + /* Save this register. */ + address += 4; + + ARMul_StoreWordS (state, address, state->Reg[temp]); + + if (state->abortSig && !state->Aborted) + { + XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); + state->Aborted = ARMul_DataAbortV; + } + } + + if (state->Aborted) + TAKEABORT; +} + +/* This function does the work of storing the registers listed in an STM + instruction when the S bit is set. The code here is always increment + after, it's up to the caller to get the input address correct and to + handle base register modification. */ + +static void +StoreSMult (ARMul_State * state, + ARMword instr, + ARMword address, + ARMword WBBase) +{ + ARMword temp; + + UNDEF_LSMNoRegs; + UNDEF_LSMPCBase; + UNDEF_LSMBaseInListWb; + + BUSUSEDINCPCN; + +#ifndef MODE32 + if (VECTORACCESS (address) || ADDREXCEPT (address)) + INTERNALABORT (address); + + if (BIT (15)) + PATCHR15; +#endif + + if (state->Bank != USERBANK) + { + /* Force User Bank. */ + (void) ARMul_SwitchMode (state, state->Mode, USER26MODE); + UNDEF_LSMUserBankWb; + } + + for (temp = 0; !BIT (temp); temp++) + ; /* N cycle first. */ + +#ifdef MODE32 + ARMul_StoreWordN (state, address, state->Reg[temp++]); +#else + if (state->Aborted) + { + (void) ARMul_LoadWordN (state, address); + + for (; temp < 16; temp++) + /* Fake the Stores as Loads. */ + if (BIT (temp)) + { + /* Save this register. */ + address += 4; + + (void) ARMul_LoadWordS (state, address); + } + + if (BIT (21) && LHSReg != 15) + LSBase = WBBase; + + TAKEABORT; + return; + } + else + ARMul_StoreWordN (state, address, state->Reg[temp++]); +#endif + + if (state->abortSig && !state->Aborted) + { + XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); + state->Aborted = ARMul_DataAbortV; + } + + /* S cycles from here on. */ + for (; temp < 16; temp++) + if (BIT (temp)) + { + /* Save this register. */ + address += 4; + + ARMul_StoreWordS (state, address, state->Reg[temp]); + + if (state->abortSig && !state->Aborted) + { + XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address); + state->Aborted = ARMul_DataAbortV; + } + } + + if (state->Mode != USER26MODE && state->Mode != USER32MODE) + /* Restore the correct bank. */ + (void) ARMul_SwitchMode (state, USER26MODE, state->Mode); + + if (BIT (21) && LHSReg != 15) + LSBase = WBBase; + + if (state->Aborted) + TAKEABORT; +} + +/* This function does the work of adding two 32bit values + together, and calculating if a carry has occurred. */ + +static ARMword +Add32 (ARMword a1, ARMword a2, int *carry) +{ + ARMword result = (a1 + a2); + unsigned int uresult = (unsigned int) result; + unsigned int ua1 = (unsigned int) a1; + + /* If (result == RdLo) and (state->Reg[nRdLo] == 0), + or (result > RdLo) then we have no carry. */ + if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1)) + *carry = 1; + else + *carry = 0; + + return result; +} + +/* This function does the work of multiplying + two 32bit values to give a 64bit result. */ + +static unsigned +Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc) +{ + /* Operand register numbers. */ + int nRdHi, nRdLo, nRs, nRm; + ARMword RdHi = 0, RdLo = 0, Rm; + /* Cycle count. */ + int scount; + + nRdHi = BITS (16, 19); + nRdLo = BITS (12, 15); + nRs = BITS (8, 11); + nRm = BITS (0, 3); + + /* Needed to calculate the cycle count. */ + Rm = state->Reg[nRm]; + + /* Check for illegal operand combinations first. */ + if ( nRdHi != 15 + && nRdLo != 15 + && nRs != 15 + && nRm != 15 + && nRdHi != nRdLo + && nRdHi != nRm + && nRdLo != nRm) + { + /* Intermediate results. */ + ARMword lo, mid1, mid2, hi; + int carry; + ARMword Rs = state->Reg[nRs]; + int sign = 0; + + if (msigned) + { + /* Compute sign of result and adjust operands if necessary. */ + sign = (Rm ^ Rs) & 0x80000000; + + if (((ARMsword) Rm) < 0) + Rm = -Rm; + + if (((ARMsword) Rs) < 0) + Rs = -Rs; + } + + /* We can split the 32x32 into four 16x16 operations. This + ensures that we do not lose precision on 32bit only hosts. */ + lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF)); + mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF)); + mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF)); + hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF)); + + /* We now need to add all of these results together, taking + care to propogate the carries from the additions. */ + RdLo = Add32 (lo, (mid1 << 16), &carry); + RdHi = carry; + RdLo = Add32 (RdLo, (mid2 << 16), &carry); + RdHi += + (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi); + + if (sign) + { + /* Negate result if necessary. */ + RdLo = ~RdLo; + RdHi = ~RdHi; + if (RdLo == 0xFFFFFFFF) + { + RdLo = 0; + RdHi += 1; + } + else + RdLo += 1; + } + + state->Reg[nRdLo] = RdLo; + state->Reg[nRdHi] = RdHi; + } + else + fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS\n"); + + if (scc) + /* Ensure that both RdHi and RdLo are used to compute Z, + but don't let RdLo's sign bit make it to N. */ + ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF)); + + /* The cycle count depends on whether the instruction is a signed or + unsigned multiply, and what bits are clear in the multiplier. */ + if (msigned && (Rm & ((unsigned) 1 << 31))) + /* Invert the bits to make the check against zero. */ + Rm = ~Rm; + + if ((Rm & 0xFFFFFF00) == 0) + scount = 1; + else if ((Rm & 0xFFFF0000) == 0) + scount = 2; + else if ((Rm & 0xFF000000) == 0) + scount = 3; + else + scount = 4; + + return 2 + scount; +} + +/* This function does the work of multiplying two 32bit + values and adding a 64bit value to give a 64bit result. */ + +static unsigned +MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc) +{ + unsigned scount; + ARMword RdLo, RdHi; + int nRdHi, nRdLo; + int carry = 0; + + nRdHi = BITS (16, 19); + nRdLo = BITS (12, 15); + + RdHi = state->Reg[nRdHi]; + RdLo = state->Reg[nRdLo]; + + scount = Multiply64 (state, instr, msigned, LDEFAULT); + + RdLo = Add32 (RdLo, state->Reg[nRdLo], &carry); + RdHi = (RdHi + state->Reg[nRdHi]) + carry; + + state->Reg[nRdLo] = RdLo; + state->Reg[nRdHi] = RdHi; + + if (scc) + /* Ensure that both RdHi and RdLo are used to compute Z, + but don't let RdLo's sign bit make it to N. */ + ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF)); + + /* Extra cycle for addition. */ + return scount + 1; +}
armemu.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: thumbemu.c =================================================================== --- thumbemu.c (nonexistent) +++ thumbemu.c (revision 816) @@ -0,0 +1,615 @@ +/* thumbemu.c -- Thumb instruction emulation. + Copyright (C) 1996, Cygnus Software Technologies Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* We can provide simple Thumb simulation by decoding the Thumb +instruction into its corresponding ARM instruction, and using the +existing ARM simulator. */ + +#ifndef MODET /* required for the Thumb instruction support */ +#if 1 +#error "MODET needs to be defined for the Thumb world to work" +#else +#define MODET (1) +#endif +#endif + +#include "armdefs.h" +#include "armemu.h" +#include "armos.h" + +/* Attempt to emulate an ARMv6 instruction. + Stores t_branch into PVALUE upon success or t_undefined otherwise. */ + +static void +handle_v6_thumb_insn (ARMul_State * state, + ARMword tinstr, + tdstate * pvalid) +{ + ARMword Rd; + ARMword Rm; + + if (! state->is_v6) + { + * pvalid = t_undefined; + return; + } + + switch (tinstr & 0xFFC0) + { + case 0xb660: /* cpsie */ + case 0xb670: /* cpsid */ + case 0x4600: /* cpy */ + case 0xba00: /* rev */ + case 0xba40: /* rev16 */ + case 0xbac0: /* revsh */ + case 0xb650: /* setend */ + default: + printf ("Unhandled v6 thumb insn: %04x\n", tinstr); + * pvalid = t_undefined; + return; + + case 0xb200: /* sxth */ + Rm = state->Reg [(tinstr & 0x38) >> 3]; + if (Rm & 0x8000) + state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000; + else + state->Reg [(tinstr & 0x7)] = Rm & 0xffff; + break; + case 0xb240: /* sxtb */ + Rm = state->Reg [(tinstr & 0x38) >> 3]; + if (Rm & 0x80) + state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00; + else + state->Reg [(tinstr & 0x7)] = Rm & 0xff; + break; + case 0xb280: /* uxth */ + Rm = state->Reg [(tinstr & 0x38) >> 3]; + state->Reg [(tinstr & 0x7)] = Rm & 0xffff; + break; + case 0xb2c0: /* uxtb */ + Rm = state->Reg [(tinstr & 0x38) >> 3]; + state->Reg [(tinstr & 0x7)] = Rm & 0xff; + break; + } + /* Indicate that the instruction has been processed. */ + * pvalid = t_branch; +} + +/* Decode a 16bit Thumb instruction. The instruction is in the low + 16-bits of the tinstr field, with the following Thumb instruction + held in the high 16-bits. Passing in two Thumb instructions allows + easier simulation of the special dual BL instruction. */ + +tdstate +ARMul_ThumbDecode (ARMul_State * state, + ARMword pc, + ARMword tinstr, + ARMword * ainstr) +{ + tdstate valid = t_decoded; /* default assumes a valid instruction */ + ARMword next_instr; + + if (state->bigendSig) + { + next_instr = tinstr & 0xFFFF; + tinstr >>= 16; + } + else + { + next_instr = tinstr >> 16; + tinstr &= 0xFFFF; + } + +#if 1 /* debugging to catch non updates */ + *ainstr = 0xDEADC0DE; +#endif + + switch ((tinstr & 0xF800) >> 11) + { + case 0: /* LSL */ + case 1: /* LSR */ + case 2: /* ASR */ + /* Format 1 */ + *ainstr = 0xE1B00000 /* base opcode */ + | ((tinstr & 0x1800) >> (11 - 5)) /* shift type */ + | ((tinstr & 0x07C0) << (7 - 6)) /* imm5 */ + | ((tinstr & 0x0038) >> 3) /* Rs */ + | ((tinstr & 0x0007) << 12); /* Rd */ + break; + case 3: /* ADD/SUB */ + /* Format 2 */ + { + ARMword subset[4] = { + 0xE0900000, /* ADDS Rd,Rs,Rn */ + 0xE0500000, /* SUBS Rd,Rs,Rn */ + 0xE2900000, /* ADDS Rd,Rs,#imm3 */ + 0xE2500000 /* SUBS Rd,Rs,#imm3 */ + }; + /* It is quicker indexing into a table, than performing switch + or conditionals: */ + *ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */ + | ((tinstr & 0x01C0) >> 6) /* Rn or imm3 */ + | ((tinstr & 0x0038) << (16 - 3)) /* Rs */ + | ((tinstr & 0x0007) << (12 - 0)); /* Rd */ + } + break; + case 4: /* MOV */ + case 5: /* CMP */ + case 6: /* ADD */ + case 7: /* SUB */ + /* Format 3 */ + { + ARMword subset[4] = { + 0xE3B00000, /* MOVS Rd,#imm8 */ + 0xE3500000, /* CMP Rd,#imm8 */ + 0xE2900000, /* ADDS Rd,Rd,#imm8 */ + 0xE2500000, /* SUBS Rd,Rd,#imm8 */ + }; + *ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */ + | ((tinstr & 0x00FF) >> 0) /* imm8 */ + | ((tinstr & 0x0700) << (16 - 8)) /* Rn */ + | ((tinstr & 0x0700) << (12 - 8)); /* Rd */ + } + break; + case 8: /* Arithmetic and high register transfers */ + /* TODO: Since the subsets for both Format 4 and Format 5 + instructions are made up of different ARM encodings, we could + save the following conditional, and just have one large + subset. */ + if ((tinstr & (1 << 10)) == 0) + { + /* Format 4 */ + struct + { + ARMword opcode; + enum + { t_norm, t_shift, t_neg, t_mul } + otype; + } + subset[16] = + { + { 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */ + { 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */ + { 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */ + { 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */ + { 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */ + { 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */ + { 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */ + { 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */ + { 0xE1100000, t_norm}, /* TST Rd,Rs */ + { 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */ + { 0xE1500000, t_norm}, /* CMP Rd,Rs */ + { 0xE1700000, t_norm}, /* CMN Rd,Rs */ + { 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */ + { 0xE0100090, t_mul} , /* MULS Rd,Rd,Rs */ + { 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */ + { 0xE1F00000, t_norm} /* MVNS Rd,Rs */ + }; + *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */ + switch (subset[(tinstr & 0x03C0) >> 6].otype) + { + case t_norm: + *ainstr |= ((tinstr & 0x0007) << 16) /* Rn */ + | ((tinstr & 0x0007) << 12) /* Rd */ + | ((tinstr & 0x0038) >> 3); /* Rs */ + break; + case t_shift: + *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */ + | ((tinstr & 0x0007) >> 0) /* Rm */ + | ((tinstr & 0x0038) << (8 - 3)); /* Rs */ + break; + case t_neg: + *ainstr |= ((tinstr & 0x0007) << 12) /* Rd */ + | ((tinstr & 0x0038) << (16 - 3)); /* Rn */ + break; + case t_mul: + *ainstr |= ((tinstr & 0x0007) << 16) /* Rd */ + | ((tinstr & 0x0007) << 8) /* Rs */ + | ((tinstr & 0x0038) >> 3); /* Rm */ + break; + } + } + else + { + /* Format 5 */ + ARMword Rd = ((tinstr & 0x0007) >> 0); + ARMword Rs = ((tinstr & 0x0038) >> 3); + if (tinstr & (1 << 7)) + Rd += 8; + if (tinstr & (1 << 6)) + Rs += 8; + switch ((tinstr & 0x03C0) >> 6) + { + case 0x1: /* ADD Rd,Rd,Hs */ + case 0x2: /* ADD Hd,Hd,Rs */ + case 0x3: /* ADD Hd,Hd,Hs */ + *ainstr = 0xE0800000 /* base */ + | (Rd << 16) /* Rn */ + | (Rd << 12) /* Rd */ + | (Rs << 0); /* Rm */ + break; + case 0x5: /* CMP Rd,Hs */ + case 0x6: /* CMP Hd,Rs */ + case 0x7: /* CMP Hd,Hs */ + *ainstr = 0xE1500000 /* base */ + | (Rd << 16) /* Rn */ + | (Rd << 12) /* Rd */ + | (Rs << 0); /* Rm */ + break; + case 0x9: /* MOV Rd,Hs */ + case 0xA: /* MOV Hd,Rs */ + case 0xB: /* MOV Hd,Hs */ + *ainstr = 0xE1A00000 /* base */ + | (Rd << 16) /* Rn */ + | (Rd << 12) /* Rd */ + | (Rs << 0); /* Rm */ + break; + case 0xC: /* BX Rs */ + case 0xD: /* BX Hs */ + *ainstr = 0xE12FFF10 /* base */ + | ((tinstr & 0x0078) >> 3); /* Rd */ + break; + case 0xE: /* UNDEFINED */ + case 0xF: /* UNDEFINED */ + if (state->is_v5) + { + /* BLX Rs; BLX Hs */ + *ainstr = 0xE12FFF30 /* base */ + | ((tinstr & 0x0078) >> 3); /* Rd */ + break; + } + /* Drop through. */ + case 0x0: /* UNDEFINED */ + case 0x4: /* UNDEFINED */ + case 0x8: /* UNDEFINED */ + handle_v6_thumb_insn (state, tinstr, & valid); + break; + } + } + break; + case 9: /* LDR Rd,[PC,#imm8] */ + /* Format 6 */ + *ainstr = 0xE59F0000 /* base */ + | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ + | ((tinstr & 0x00FF) << (2 - 0)); /* off8 */ + break; + case 10: + case 11: + /* TODO: Format 7 and Format 8 perform the same ARM encoding, so + the following could be merged into a single subset, saving on + the following boolean: */ + if ((tinstr & (1 << 9)) == 0) + { + /* Format 7 */ + ARMword subset[4] = { + 0xE7800000, /* STR Rd,[Rb,Ro] */ + 0xE7C00000, /* STRB Rd,[Rb,Ro] */ + 0xE7900000, /* LDR Rd,[Rb,Ro] */ + 0xE7D00000 /* LDRB Rd,[Rb,Ro] */ + }; + *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */ + | ((tinstr & 0x0007) << (12 - 0)) /* Rd */ + | ((tinstr & 0x0038) << (16 - 3)) /* Rb */ + | ((tinstr & 0x01C0) >> 6); /* Ro */ + } + else + { + /* Format 8 */ + ARMword subset[4] = { + 0xE18000B0, /* STRH Rd,[Rb,Ro] */ + 0xE19000D0, /* LDRSB Rd,[Rb,Ro] */ + 0xE19000B0, /* LDRH Rd,[Rb,Ro] */ + 0xE19000F0 /* LDRSH Rd,[Rb,Ro] */ + }; + *ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */ + | ((tinstr & 0x0007) << (12 - 0)) /* Rd */ + | ((tinstr & 0x0038) << (16 - 3)) /* Rb */ + | ((tinstr & 0x01C0) >> 6); /* Ro */ + } + break; + case 12: /* STR Rd,[Rb,#imm5] */ + case 13: /* LDR Rd,[Rb,#imm5] */ + case 14: /* STRB Rd,[Rb,#imm5] */ + case 15: /* LDRB Rd,[Rb,#imm5] */ + /* Format 9 */ + { + ARMword subset[4] = { + 0xE5800000, /* STR Rd,[Rb,#imm5] */ + 0xE5900000, /* LDR Rd,[Rb,#imm5] */ + 0xE5C00000, /* STRB Rd,[Rb,#imm5] */ + 0xE5D00000 /* LDRB Rd,[Rb,#imm5] */ + }; + /* The offset range defends on whether we are transferring a + byte or word value: */ + *ainstr = subset[(tinstr & 0x1800) >> 11] /* base */ + | ((tinstr & 0x0007) << (12 - 0)) /* Rd */ + | ((tinstr & 0x0038) << (16 - 3)) /* Rb */ + | ((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */ + } + break; + case 16: /* STRH Rd,[Rb,#imm5] */ + case 17: /* LDRH Rd,[Rb,#imm5] */ + /* Format 10 */ + *ainstr = ((tinstr & (1 << 11)) /* base */ + ? 0xE1D000B0 /* LDRH */ + : 0xE1C000B0) /* STRH */ + | ((tinstr & 0x0007) << (12 - 0)) /* Rd */ + | ((tinstr & 0x0038) << (16 - 3)) /* Rb */ + | ((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */ + | ((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */ + break; + case 18: /* STR Rd,[SP,#imm8] */ + case 19: /* LDR Rd,[SP,#imm8] */ + /* Format 11 */ + *ainstr = ((tinstr & (1 << 11)) /* base */ + ? 0xE59D0000 /* LDR */ + : 0xE58D0000) /* STR */ + | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ + | ((tinstr & 0x00FF) << 2); /* off8 */ + break; + case 20: /* ADD Rd,PC,#imm8 */ + case 21: /* ADD Rd,SP,#imm8 */ + /* Format 12 */ + if ((tinstr & (1 << 11)) == 0) + { + /* NOTE: The PC value used here should by word aligned */ + /* We encode shift-left-by-2 in the rotate immediate field, + so no shift of off8 is needed. */ + *ainstr = 0xE28F0F00 /* base */ + | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ + | (tinstr & 0x00FF); /* off8 */ + } + else + { + /* We encode shift-left-by-2 in the rotate immediate field, + so no shift of off8 is needed. */ + *ainstr = 0xE28D0F00 /* base */ + | ((tinstr & 0x0700) << (12 - 8)) /* Rd */ + | (tinstr & 0x00FF); /* off8 */ + } + break; + case 22: + case 23: + switch (tinstr & 0x0F00) + { + case 0x0000: + /* Format 13 */ + /* NOTE: The instruction contains a shift left of 2 + equivalent (implemented as ROR #30): */ + *ainstr = ((tinstr & (1 << 7)) /* base */ + ? 0xE24DDF00 /* SUB */ + : 0xE28DDF00) /* ADD */ + | (tinstr & 0x007F); /* off7 */ + break; + case 0x0400: + /* Format 14 - Push */ + * ainstr = 0xE92D0000 | (tinstr & 0x00FF); + break; + case 0x0500: + /* Format 14 - Push + LR */ + * ainstr = 0xE92D4000 | (tinstr & 0x00FF); + break; + case 0x0c00: + /* Format 14 - Pop */ + * ainstr = 0xE8BD0000 | (tinstr & 0x00FF); + break; + case 0x0d00: + /* Format 14 - Pop + PC */ + * ainstr = 0xE8BD8000 | (tinstr & 0x00FF); + break; + case 0x0e00: + if (state->is_v5) + { + /* This is normally an undefined instruction. The v5t architecture + defines this particular pattern as a BKPT instruction, for + hardware assisted debugging. We map onto the arm BKPT + instruction. */ + * ainstr = 0xE1200070 | ((tinstr & 0xf0) << 4) | (tinstr & 0xf); + break; + } + /* Drop through. */ + default: + /* Everything else is an undefined instruction. */ + handle_v6_thumb_insn (state, tinstr, & valid); + break; + } + break; + case 24: /* STMIA */ + case 25: /* LDMIA */ + /* Format 15 */ + *ainstr = ((tinstr & (1 << 11)) /* base */ + ? 0xE8B00000 /* LDMIA */ + : 0xE8A00000) /* STMIA */ + | ((tinstr & 0x0700) << (16 - 8)) /* Rb */ + | (tinstr & 0x00FF); /* mask8 */ + break; + case 26: /* Bcc */ + case 27: /* Bcc/SWI */ + if ((tinstr & 0x0F00) == 0x0F00) + { + /* Format 17 : SWI */ + *ainstr = 0xEF000000; + /* Breakpoint must be handled specially. */ + if ((tinstr & 0x00FF) == 0x18) + *ainstr |= ((tinstr & 0x00FF) << 16); + /* New breakpoint value. See gdb/arm-tdep.c */ + else if ((tinstr & 0x00FF) == 0xFE) + *ainstr |= SWI_Breakpoint; + else + *ainstr |= (tinstr & 0x00FF); + } + else if ((tinstr & 0x0F00) != 0x0E00) + { + /* Format 16 */ + int doit = FALSE; + /* TODO: Since we are doing a switch here, we could just add + the SWI and undefined instruction checks into this + switch to same on a couple of conditionals: */ + switch ((tinstr & 0x0F00) >> 8) + { + case EQ: + doit = ZFLAG; + break; + case NE: + doit = !ZFLAG; + break; + case VS: + doit = VFLAG; + break; + case VC: + doit = !VFLAG; + break; + case MI: + doit = NFLAG; + break; + case PL: + doit = !NFLAG; + break; + case CS: + doit = CFLAG; + break; + case CC: + doit = !CFLAG; + break; + case HI: + doit = (CFLAG && !ZFLAG); + break; + case LS: + doit = (!CFLAG || ZFLAG); + break; + case GE: + doit = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); + break; + case LT: + doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); + break; + case GT: + doit = ((!NFLAG && !VFLAG && !ZFLAG) + || (NFLAG && VFLAG && !ZFLAG)); + break; + case LE: + doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG; + break; + } + if (doit) + { + state->Reg[15] = (pc + 4 + + (((tinstr & 0x7F) << 1) + | ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0))); + FLUSHPIPE; + } + valid = t_branch; + } + else + /* UNDEFINED : cc=1110(AL) uses different format. */ + handle_v6_thumb_insn (state, tinstr, & valid); + break; + case 28: /* B */ + /* Format 18 */ + state->Reg[15] = (pc + 4 + + (((tinstr & 0x3FF) << 1) + | ((tinstr & (1 << 10)) ? 0xFFFFF800 : 0))); + FLUSHPIPE; + valid = t_branch; + break; + case 29: /* UNDEFINED */ + if (state->is_v5) + { + if (tinstr & 1) + { + handle_v6_thumb_insn (state, tinstr, & valid); + break; + } + /* Drop through. */ + + /* Format 19 */ + /* There is no single ARM instruction equivalent for this + instruction. Also, it should only ever be matched with the + fmt19 "BL/BLX instruction 1" instruction. However, we do + allow the simulation of it on its own, with undefined results + if r14 is not suitably initialised. */ + { + ARMword tmp = (pc + 2); + + state->Reg[15] = ((state->Reg[14] + ((tinstr & 0x07FF) << 1)) + & 0xFFFFFFFC); + CLEART; + state->Reg[14] = (tmp | 1); + valid = t_branch; + FLUSHPIPE; + break; + } + } + + handle_v6_thumb_insn (state, tinstr, & valid); + break; + + case 30: /* BL instruction 1 */ + /* Format 19 */ + /* There is no single ARM instruction equivalent for this Thumb + instruction. To keep the simulation simple (from the user + perspective) we check if the following instruction is the + second half of this BL, and if it is we simulate it + immediately. */ + state->Reg[14] = state->Reg[15] \ + + (((tinstr & 0x07FF) << 12) \ + | ((tinstr & (1 << 10)) ? 0xFF800000 : 0)); + + valid = t_branch; /* in-case we don't have the 2nd half */ + tinstr = next_instr; /* move the instruction down */ + pc += 2; /* point the pc at the 2nd half */ + if (((tinstr & 0xF800) >> 11) != 31) + { + if (((tinstr & 0xF800) >> 11) == 29) + { + ARMword tmp = (pc + 2); + + state->Reg[15] = ((state->Reg[14] + + ((tinstr & 0x07FE) << 1)) + & 0xFFFFFFFC); + CLEART; + state->Reg[14] = (tmp | 1); + valid = t_branch; + FLUSHPIPE; + } + else + /* Exit, since not correct instruction. */ + pc -= 2; + break; + } + /* else we fall through to process the second half of the BL */ + pc += 2; /* point the pc at the 2nd half */ + case 31: /* BL instruction 2 */ + /* Format 19 */ + /* There is no single ARM instruction equivalent for this + instruction. Also, it should only ever be matched with the + fmt19 "BL instruction 1" instruction. However, we do allow + the simulation of it on its own, with undefined results if + r14 is not suitably initialised. */ + { + ARMword tmp = pc; + + state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1)); + state->Reg[14] = (tmp | 1); + valid = t_branch; + FLUSHPIPE; + } + break; + } + + return valid; +}
thumbemu.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: armsupp.c =================================================================== --- armsupp.c (nonexistent) +++ armsupp.c (revision 816) @@ -0,0 +1,821 @@ +/* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include "armdefs.h" +#include "armemu.h" +#include "ansidecl.h" + +/* Definitions for the support routines. */ + +static ARMword ModeToBank (ARMword); +static void EnvokeList (ARMul_State *, unsigned long, unsigned long); + +struct EventNode +{ /* An event list node. */ + unsigned (*func) (ARMul_State *); /* The function to call. */ + struct EventNode *next; +}; + +/* This routine returns the value of a register from a mode. */ + +ARMword +ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg) +{ + mode &= MODEBITS; + if (mode != state->Mode) + return (state->RegBank[ModeToBank ((ARMword) mode)][reg]); + else + return (state->Reg[reg]); +} + +/* This routine sets the value of a register for a mode. */ + +void +ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value) +{ + mode &= MODEBITS; + if (mode != state->Mode) + state->RegBank[ModeToBank ((ARMword) mode)][reg] = value; + else + state->Reg[reg] = value; +} + +/* This routine returns the value of the PC, mode independently. */ + +ARMword +ARMul_GetPC (ARMul_State * state) +{ + if (state->Mode > SVC26MODE) + return state->Reg[15]; + else + return R15PC; +} + +/* This routine returns the value of the PC, mode independently. */ + +ARMword +ARMul_GetNextPC (ARMul_State * state) +{ + if (state->Mode > SVC26MODE) + return state->Reg[15] + isize; + else + return (state->Reg[15] + isize) & R15PCBITS; +} + +/* This routine sets the value of the PC. */ + +void +ARMul_SetPC (ARMul_State * state, ARMword value) +{ + if (ARMul_MODE32BIT) + state->Reg[15] = value & PCBITS; + else + state->Reg[15] = R15CCINTMODE | (value & R15PCBITS); + FLUSHPIPE; +} + +/* This routine returns the value of register 15, mode independently. */ + +ARMword +ARMul_GetR15 (ARMul_State * state) +{ + if (state->Mode > SVC26MODE) + return (state->Reg[15]); + else + return (R15PC | ECC | ER15INT | EMODE); +} + +/* This routine sets the value of Register 15. */ + +void +ARMul_SetR15 (ARMul_State * state, ARMword value) +{ + if (ARMul_MODE32BIT) + state->Reg[15] = value & PCBITS; + else + { + state->Reg[15] = value; + ARMul_R15Altered (state); + } + FLUSHPIPE; +} + +/* This routine returns the value of the CPSR. */ + +ARMword +ARMul_GetCPSR (ARMul_State * state) +{ + return (CPSR | state->Cpsr); +} + +/* This routine sets the value of the CPSR. */ + +void +ARMul_SetCPSR (ARMul_State * state, ARMword value) +{ + state->Cpsr = value; + ARMul_CPSRAltered (state); +} + +/* This routine does all the nasty bits involved in a write to the CPSR, + including updating the register bank, given a MSR instruction. */ + +void +ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs) +{ + state->Cpsr = ARMul_GetCPSR (state); + + if (state->Mode != USER26MODE + && state->Mode != USER32MODE) + { + /* In user mode, only write flags. */ + if (BIT (16)) + SETPSR_C (state->Cpsr, rhs); + if (BIT (17)) + SETPSR_X (state->Cpsr, rhs); + if (BIT (18)) + SETPSR_S (state->Cpsr, rhs); + } + if (BIT (19)) + SETPSR_F (state->Cpsr, rhs); + ARMul_CPSRAltered (state); +} + +/* Get an SPSR from the specified mode. */ + +ARMword +ARMul_GetSPSR (ARMul_State * state, ARMword mode) +{ + ARMword bank = ModeToBank (mode & MODEBITS); + + if (! BANK_CAN_ACCESS_SPSR (bank)) + return ARMul_GetCPSR (state); + + return state->Spsr[bank]; +} + +/* This routine does a write to an SPSR. */ + +void +ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value) +{ + ARMword bank = ModeToBank (mode & MODEBITS); + + if (BANK_CAN_ACCESS_SPSR (bank)) + state->Spsr[bank] = value; +} + +/* This routine does a write to the current SPSR, given an MSR instruction. */ + +void +ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs) +{ + if (BANK_CAN_ACCESS_SPSR (state->Bank)) + { + if (BIT (16)) + SETPSR_C (state->Spsr[state->Bank], rhs); + if (BIT (17)) + SETPSR_X (state->Spsr[state->Bank], rhs); + if (BIT (18)) + SETPSR_S (state->Spsr[state->Bank], rhs); + if (BIT (19)) + SETPSR_F (state->Spsr[state->Bank], rhs); + } +} + +/* This routine updates the state of the emulator after the Cpsr has been + changed. Both the processor flags and register bank are updated. */ + +void +ARMul_CPSRAltered (ARMul_State * state) +{ + ARMword oldmode; + + if (state->prog32Sig == LOW) + state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS); + + oldmode = state->Mode; + + if (state->Mode != (state->Cpsr & MODEBITS)) + { + state->Mode = + ARMul_SwitchMode (state, state->Mode, state->Cpsr & MODEBITS); + + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + } + state->Cpsr &= ~MODEBITS; + + ASSIGNINT (state->Cpsr & INTBITS); + state->Cpsr &= ~INTBITS; + ASSIGNN ((state->Cpsr & NBIT) != 0); + state->Cpsr &= ~NBIT; + ASSIGNZ ((state->Cpsr & ZBIT) != 0); + state->Cpsr &= ~ZBIT; + ASSIGNC ((state->Cpsr & CBIT) != 0); + state->Cpsr &= ~CBIT; + ASSIGNV ((state->Cpsr & VBIT) != 0); + state->Cpsr &= ~VBIT; + ASSIGNS ((state->Cpsr & SBIT) != 0); + state->Cpsr &= ~SBIT; +#ifdef MODET + ASSIGNT ((state->Cpsr & TBIT) != 0); + state->Cpsr &= ~TBIT; +#endif + + if (oldmode > SVC26MODE) + { + if (state->Mode <= SVC26MODE) + { + state->Emulate = CHANGEMODE; + state->Reg[15] = ECC | ER15INT | EMODE | R15PC; + } + } + else + { + if (state->Mode > SVC26MODE) + { + state->Emulate = CHANGEMODE; + state->Reg[15] = R15PC; + } + else + state->Reg[15] = ECC | ER15INT | EMODE | R15PC; + } +} + +/* This routine updates the state of the emulator after register 15 has + been changed. Both the processor flags and register bank are updated. + This routine should only be called from a 26 bit mode. */ + +void +ARMul_R15Altered (ARMul_State * state) +{ + if (state->Mode != R15MODE) + { + state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE); + state->NtransSig = (state->Mode & 3) ? HIGH : LOW; + } + + if (state->Mode > SVC26MODE) + state->Emulate = CHANGEMODE; + + ASSIGNR15INT (R15INT); + + ASSIGNN ((state->Reg[15] & NBIT) != 0); + ASSIGNZ ((state->Reg[15] & ZBIT) != 0); + ASSIGNC ((state->Reg[15] & CBIT) != 0); + ASSIGNV ((state->Reg[15] & VBIT) != 0); +} + +/* This routine controls the saving and restoring of registers across mode + changes. The regbank matrix is largely unused, only rows 13 and 14 are + used across all modes, 8 to 14 are used for FIQ, all others use the USER + column. It's easier this way. old and new parameter are modes numbers. + Notice the side effect of changing the Bank variable. */ + +ARMword +ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode) +{ + unsigned i; + ARMword oldbank; + ARMword newbank; + + oldbank = ModeToBank (oldmode); + newbank = state->Bank = ModeToBank (newmode); + + /* Do we really need to do it? */ + if (oldbank != newbank) + { + /* Save away the old registers. */ + switch (oldbank) + { + case USERBANK: + case IRQBANK: + case SVCBANK: + case ABORTBANK: + case UNDEFBANK: + if (newbank == FIQBANK) + for (i = 8; i < 13; i++) + state->RegBank[USERBANK][i] = state->Reg[i]; + state->RegBank[oldbank][13] = state->Reg[13]; + state->RegBank[oldbank][14] = state->Reg[14]; + break; + case FIQBANK: + for (i = 8; i < 15; i++) + state->RegBank[FIQBANK][i] = state->Reg[i]; + break; + case DUMMYBANK: + for (i = 8; i < 15; i++) + state->RegBank[DUMMYBANK][i] = 0; + break; + default: + abort (); + } + + /* Restore the new registers. */ + switch (newbank) + { + case USERBANK: + case IRQBANK: + case SVCBANK: + case ABORTBANK: + case UNDEFBANK: + if (oldbank == FIQBANK) + for (i = 8; i < 13; i++) + state->Reg[i] = state->RegBank[USERBANK][i]; + state->Reg[13] = state->RegBank[newbank][13]; + state->Reg[14] = state->RegBank[newbank][14]; + break; + case FIQBANK: + for (i = 8; i < 15; i++) + state->Reg[i] = state->RegBank[FIQBANK][i]; + break; + case DUMMYBANK: + for (i = 8; i < 15; i++) + state->Reg[i] = 0; + break; + default: + abort (); + } + } + + return newmode; +} + +/* Given a processor mode, this routine returns the + register bank that will be accessed in that mode. */ + +static ARMword +ModeToBank (ARMword mode) +{ + static ARMword bankofmode[] = + { + USERBANK, FIQBANK, IRQBANK, SVCBANK, + DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, + DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, + DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK, + USERBANK, FIQBANK, IRQBANK, SVCBANK, + DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK, + DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK, + DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK + }; + + if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0]))) + return DUMMYBANK; + + return bankofmode[mode]; +} + +/* Returns the register number of the nth register in a reg list. */ + +unsigned +ARMul_NthReg (ARMword instr, unsigned number) +{ + unsigned bit, upto; + + for (bit = 0, upto = 0; upto <= number; bit ++) + if (BIT (bit)) + upto ++; + + return (bit - 1); +} + +/* Assigns the N and Z flags depending on the value of result. */ + +void +ARMul_NegZero (ARMul_State * state, ARMword result) +{ + if (NEG (result)) + { + SETN; + CLEARZ; + } + else if (result == 0) + { + CLEARN; + SETZ; + } + else + { + CLEARN; + CLEARZ; + } +} + +/* Compute whether an addition of A and B, giving RESULT, overflowed. */ + +int +AddOverflow (ARMword a, ARMword b, ARMword result) +{ + return ((NEG (a) && NEG (b) && POS (result)) + || (POS (a) && POS (b) && NEG (result))); +} + +/* Compute whether a subtraction of A and B, giving RESULT, overflowed. */ + +int +SubOverflow (ARMword a, ARMword b, ARMword result) +{ + return ((NEG (a) && POS (b) && POS (result)) + || (POS (a) && NEG (b) && NEG (result))); +} + +/* Assigns the C flag after an addition of a and b to give result. */ + +void +ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result) +{ + ASSIGNC ((NEG (a) && NEG (b)) || + (NEG (a) && POS (result)) || (NEG (b) && POS (result))); +} + +/* Assigns the V flag after an addition of a and b to give result. */ + +void +ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result) +{ + ASSIGNV (AddOverflow (a, b, result)); +} + +/* Assigns the C flag after an subtraction of a and b to give result. */ + +void +ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result) +{ + ASSIGNC ((NEG (a) && POS (b)) || + (NEG (a) && POS (result)) || (POS (b) && POS (result))); +} + +/* Assigns the V flag after an subtraction of a and b to give result. */ + +void +ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result) +{ + ASSIGNV (SubOverflow (a, b, result)); +} + +/* This function does the work of generating the addresses used in an + LDC instruction. The code here is always post-indexed, it's up to the + caller to get the input address correct and to handle base register + modification. It also handles the Busy-Waiting. */ + +void +ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address) +{ + unsigned cpab; + ARMword data; + + UNDEF_LSCPCBaseWb; + + if (! CP_ACCESS_ALLOWED (state, CPNum)) + { + ARMul_UndefInstr (state, instr); + return; + } + + if (ADDREXCEPT (address)) + INTERNALABORT (address); + + cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0); + while (cpab == ARMul_BUSY) + { + ARMul_Icycles (state, 1, 0); + + if (IntPending (state)) + { + cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT, instr, 0); + return; + } + else + cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr, 0); + } + if (cpab == ARMul_CANT) + { + CPTAKEABORT; + return; + } + + cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0); + data = ARMul_LoadWordN (state, address); + BUSUSEDINCPCN; + + if (BIT (21)) + LSBase = state->Base; + cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data); + + while (cpab == ARMul_INC) + { + address += 4; + data = ARMul_LoadWordN (state, address); + cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data); + } + + if (state->abortSig || state->Aborted) + TAKEABORT; +} + +/* This function does the work of generating the addresses used in an + STC instruction. The code here is always post-indexed, it's up to the + caller to get the input address correct and to handle base register + modification. It also handles the Busy-Waiting. */ + +void +ARMul_STC (ARMul_State * state, ARMword instr, ARMword address) +{ + unsigned cpab; + ARMword data; + + UNDEF_LSCPCBaseWb; + + if (! CP_ACCESS_ALLOWED (state, CPNum)) + { + ARMul_UndefInstr (state, instr); + return; + } + + if (ADDREXCEPT (address) || VECTORACCESS (address)) + INTERNALABORT (address); + + cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data); + while (cpab == ARMul_BUSY) + { + ARMul_Icycles (state, 1, 0); + if (IntPending (state)) + { + cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT, instr, 0); + return; + } + else + cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr, &data); + } + + if (cpab == ARMul_CANT) + { + CPTAKEABORT; + return; + } +#ifndef MODE32 + if (ADDREXCEPT (address) || VECTORACCESS (address)) + INTERNALABORT (address); +#endif + BUSUSEDINCPCN; + if (BIT (21)) + LSBase = state->Base; + cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data); + ARMul_StoreWordN (state, address, data); + + while (cpab == ARMul_INC) + { + address += 4; + cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data); + ARMul_StoreWordN (state, address, data); + } + + if (state->abortSig || state->Aborted) + TAKEABORT; +} + +/* This function does the Busy-Waiting for an MCR instruction. */ + +void +ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source) +{ + unsigned cpab; + + if (! CP_ACCESS_ALLOWED (state, CPNum)) + { + ARMul_UndefInstr (state, instr); + return; + } + + cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source); + + while (cpab == ARMul_BUSY) + { + ARMul_Icycles (state, 1, 0); + + if (IntPending (state)) + { + cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT, instr, 0); + return; + } + else + cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr, source); + } + + if (cpab == ARMul_CANT) + ARMul_Abort (state, ARMul_UndefinedInstrV); + else + { + BUSUSEDINCPCN; + ARMul_Ccycles (state, 1, 0); + } +} + +/* This function does the Busy-Waiting for an MRC instruction. */ + +ARMword +ARMul_MRC (ARMul_State * state, ARMword instr) +{ + unsigned cpab; + ARMword result = 0; + + if (! CP_ACCESS_ALLOWED (state, CPNum)) + { + ARMul_UndefInstr (state, instr); + return; + } + + cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result); + while (cpab == ARMul_BUSY) + { + ARMul_Icycles (state, 1, 0); + if (IntPending (state)) + { + cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT, instr, 0); + return (0); + } + else + cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr, &result); + } + if (cpab == ARMul_CANT) + { + ARMul_Abort (state, ARMul_UndefinedInstrV); + /* Parent will destroy the flags otherwise. */ + result = ECC; + } + else + { + BUSUSEDINCPCN; + ARMul_Ccycles (state, 1, 0); + ARMul_Icycles (state, 1, 0); + } + + return result; +} + +/* This function does the Busy-Waiting for an CDP instruction. */ + +void +ARMul_CDP (ARMul_State * state, ARMword instr) +{ + unsigned cpab; + + if (! CP_ACCESS_ALLOWED (state, CPNum)) + { + ARMul_UndefInstr (state, instr); + return; + } + + cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr); + while (cpab == ARMul_BUSY) + { + ARMul_Icycles (state, 1, 0); + if (IntPending (state)) + { + cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT, instr); + return; + } + else + cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr); + } + if (cpab == ARMul_CANT) + ARMul_Abort (state, ARMul_UndefinedInstrV); + else + BUSUSEDN; +} + +/* This function handles Undefined instructions, as CP isntruction. */ + +void +ARMul_UndefInstr (ARMul_State * state, ARMword instr ATTRIBUTE_UNUSED) +{ + ARMul_Abort (state, ARMul_UndefinedInstrV); +} + +/* Return TRUE if an interrupt is pending, FALSE otherwise. */ + +unsigned +IntPending (ARMul_State * state) +{ + if (state->Exception) + { + /* Any exceptions. */ + if (state->NresetSig == LOW) + { + ARMul_Abort (state, ARMul_ResetV); + return TRUE; + } + else if (!state->NfiqSig && !FFLAG) + { + ARMul_Abort (state, ARMul_FIQV); + return TRUE; + } + else if (!state->NirqSig && !IFLAG) + { + ARMul_Abort (state, ARMul_IRQV); + return TRUE; + } + } + + return FALSE; +} + +/* Align a word access to a non word boundary. */ + +ARMword +ARMul_Align (state, address, data) + ARMul_State * state ATTRIBUTE_UNUSED; + ARMword address; + ARMword data; +{ + /* This code assumes the address is really unaligned, + as a shift by 32 is undefined in C. */ + + address = (address & 3) << 3; /* Get the word address. */ + return ((data >> address) | (data << (32 - address))); /* rot right */ +} + +/* This routine is used to call another routine after a certain number of + cycles have been executed. The first parameter is the number of cycles + delay before the function is called, the second argument is a pointer + to the function. A delay of zero doesn't work, just call the function. */ + +void +ARMul_ScheduleEvent (ARMul_State * state, unsigned long delay, + unsigned (*what) (ARMul_State *)) +{ + unsigned long when; + struct EventNode *event; + + if (state->EventSet++ == 0) + state->Now = ARMul_Time (state); + when = (state->Now + delay) % EVENTLISTSIZE; + event = (struct EventNode *) malloc (sizeof (struct EventNode)); + event->func = what; + event->next = *(state->EventPtr + when); + *(state->EventPtr + when) = event; +} + +/* This routine is called at the beginning of + every cycle, to envoke scheduled events. */ + +void +ARMul_EnvokeEvent (ARMul_State * state) +{ + static unsigned long then; + + then = state->Now; + state->Now = ARMul_Time (state) % EVENTLISTSIZE; + if (then < state->Now) + /* Schedule events. */ + EnvokeList (state, then, state->Now); + else if (then > state->Now) + { + /* Need to wrap around the list. */ + EnvokeList (state, then, EVENTLISTSIZE - 1L); + EnvokeList (state, 0L, state->Now); + } +} + +/* Envokes all the entries in a range. */ + +static void +EnvokeList (ARMul_State * state, unsigned long from, unsigned long to) +{ + for (; from <= to; from++) + { + struct EventNode *anevent; + + anevent = *(state->EventPtr + from); + while (anevent) + { + (anevent->func) (state); + state->EventSet--; + anevent = anevent->next; + } + *(state->EventPtr + from) = NULL; + } +} + +/* This routine is returns the number of clock ticks since the last reset. */ + +unsigned long +ARMul_Time (ARMul_State * state) +{ + return (state->NumScycles + state->NumNcycles + + state->NumIcycles + state->NumCcycles + state->NumFcycles); +}
armsupp.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: iwmmxt.h =================================================================== --- iwmmxt.h (nonexistent) +++ iwmmxt.h (revision 816) @@ -0,0 +1,27 @@ +/* iwmmxt.h -- Intel(r) Wireless MMX(tm) technology co-processor interface. + Copyright (C) 2002, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + Contributed by matthew green (mrg@redhat.com). + + 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 unsigned IwmmxtLDC (ARMul_State *, unsigned, ARMword, ARMword); +extern unsigned IwmmxtSTC (ARMul_State *, unsigned, ARMword, ARMword *); +extern unsigned IwmmxtMCR (ARMul_State *, unsigned, ARMword, ARMword); +extern unsigned IwmmxtMRC (ARMul_State *, unsigned, ARMword, ARMword *); +extern unsigned IwmmxtCDP (ARMul_State *, unsigned, ARMword); + +extern int ARMul_HandleIwmmxt (ARMul_State *, ARMword); + +extern int Fetch_Iwmmxt_Register (unsigned int, unsigned char *); +extern int Store_Iwmmxt_Register (unsigned int, unsigned char *);
iwmmxt.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: armopts.h =================================================================== --- armopts.h (nonexistent) +++ armopts.h (revision 816) @@ -0,0 +1,23 @@ +/* armopts.h -- ARMulator configuration options: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Define one of ARM60 or ARM61 */ +#ifndef ARM60 +#ifndef ARM61 +#define ARM60 +#endif +#endif
armopts.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: armemu.h =================================================================== --- armemu.h (nonexistent) +++ armemu.h (revision 816) @@ -0,0 +1,545 @@ +/* armemu.h -- ARMulator emulation macros: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +extern ARMword isize; + +/* Condition code values. */ +#define EQ 0 +#define NE 1 +#define CS 2 +#define CC 3 +#define MI 4 +#define PL 5 +#define VS 6 +#define VC 7 +#define HI 8 +#define LS 9 +#define GE 10 +#define LT 11 +#define GT 12 +#define LE 13 +#define AL 14 +#define NV 15 + +/* Shift Opcodes. */ +#define LSL 0 +#define LSR 1 +#define ASR 2 +#define ROR 3 + +/* Macros to twiddle the status flags and mode. */ +#define NBIT ((unsigned)1L << 31) +#define ZBIT (1L << 30) +#define CBIT (1L << 29) +#define VBIT (1L << 28) +#define SBIT (1L << 27) +#define IBIT (1L << 7) +#define FBIT (1L << 6) +#define IFBITS (3L << 6) +#define R15IBIT (1L << 27) +#define R15FBIT (1L << 26) +#define R15IFBITS (3L << 26) + +#define POS(i) ( (~(i)) >> 31 ) +#define NEG(i) ( (i) >> 31 ) + +#ifdef MODET /* Thumb support. */ +/* ??? This bit is actually in the low order bit of the PC in the hardware. + It isn't clear if the simulator needs to model that or not. */ +#define TBIT (1L << 5) +#define TFLAG state->TFlag +#define SETT state->TFlag = 1 +#define CLEART state->TFlag = 0 +#define ASSIGNT(res) state->TFlag = res +#define INSN_SIZE (TFLAG ? 2 : 4) +#else +#define INSN_SIZE 4 +#endif + +#define NFLAG state->NFlag +#define SETN state->NFlag = 1 +#define CLEARN state->NFlag = 0 +#define ASSIGNN(res) state->NFlag = res + +#define ZFLAG state->ZFlag +#define SETZ state->ZFlag = 1 +#define CLEARZ state->ZFlag = 0 +#define ASSIGNZ(res) state->ZFlag = res + +#define CFLAG state->CFlag +#define SETC state->CFlag = 1 +#define CLEARC state->CFlag = 0 +#define ASSIGNC(res) state->CFlag = res + +#define VFLAG state->VFlag +#define SETV state->VFlag = 1 +#define CLEARV state->VFlag = 0 +#define ASSIGNV(res) state->VFlag = res + +#define SFLAG state->SFlag +#define SETS state->SFlag = 1 +#define CLEARS state->SFlag = 0 +#define ASSIGNS(res) state->SFlag = res + +#define IFLAG (state->IFFlags >> 1) +#define FFLAG (state->IFFlags & 1) +#define IFFLAGS state->IFFlags +#define ASSIGNINT(res) state->IFFlags = (((res) >> 6) & 3) +#define ASSIGNR15INT(res) state->IFFlags = (((res) >> 26) & 3) ; + +#define PSR_FBITS (0xff000000L) +#define PSR_SBITS (0x00ff0000L) +#define PSR_XBITS (0x0000ff00L) +#define PSR_CBITS (0x000000ffL) + +#if defined MODE32 || defined MODET +#define CCBITS (0xf8000000L) +#else +#define CCBITS (0xf0000000L) +#endif + +#define INTBITS (0xc0L) + +#if defined MODET && defined MODE32 +#define PCBITS (0xffffffffL) +#else +#define PCBITS (0xfffffffcL) +#endif + +#define MODEBITS (0x1fL) +#define R15INTBITS (3L << 26) + +#if defined MODET && defined MODE32 +#define R15PCBITS (0x03ffffffL) +#else +#define R15PCBITS (0x03fffffcL) +#endif + +#define R15PCMODEBITS (0x03ffffffL) +#define R15MODEBITS (0x3L) + +#ifdef MODE32 +#define PCMASK PCBITS +#define PCWRAP(pc) (pc) +#else +#define PCMASK R15PCBITS +#define PCWRAP(pc) ((pc) & R15PCBITS) +#endif + +#define PC (state->Reg[15] & PCMASK) +#define R15CCINTMODE (state->Reg[15] & (CCBITS | R15INTBITS | R15MODEBITS)) +#define R15INT (state->Reg[15] & R15INTBITS) +#define R15INTPC (state->Reg[15] & (R15INTBITS | R15PCBITS)) +#define R15INTPCMODE (state->Reg[15] & (R15INTBITS | R15PCBITS | R15MODEBITS)) +#define R15INTMODE (state->Reg[15] & (R15INTBITS | R15MODEBITS)) +#define R15PC (state->Reg[15] & R15PCBITS) +#define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS)) +#define R15MODE (state->Reg[15] & R15MODEBITS) + +#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (SFLAG << 27)) +#define EINT (IFFLAGS << 6) +#define ER15INT (IFFLAGS << 26) +#define EMODE (state->Mode) + +#ifdef MODET +#define CPSR (ECC | EINT | EMODE | (TFLAG << 5)) +#else +#define CPSR (ECC | EINT | EMODE) +#endif + +#ifdef MODE32 +#define PATCHR15 +#else +#define PATCHR15 state->Reg[15] = ECC | ER15INT | EMODE | R15PC +#endif + +#define GETSPSR(bank) (ARMul_GetSPSR (state, EMODE)) +#define SETPSR_F(d,s) d = ((d) & ~PSR_FBITS) | ((s) & PSR_FBITS) +#define SETPSR_S(d,s) d = ((d) & ~PSR_SBITS) | ((s) & PSR_SBITS) +#define SETPSR_X(d,s) d = ((d) & ~PSR_XBITS) | ((s) & PSR_XBITS) +#define SETPSR_C(d,s) d = ((d) & ~PSR_CBITS) | ((s) & PSR_CBITS) + +#define SETR15PSR(s) \ + do \ + { \ + if (state->Mode == USER26MODE) \ + { \ + state->Reg[15] = ((s) & CCBITS) | R15PC | ER15INT | EMODE; \ + ASSIGNN ((state->Reg[15] & NBIT) != 0); \ + ASSIGNZ ((state->Reg[15] & ZBIT) != 0); \ + ASSIGNC ((state->Reg[15] & CBIT) != 0); \ + ASSIGNV ((state->Reg[15] & VBIT) != 0); \ + } \ + else \ + { \ + state->Reg[15] = R15PC | ((s) & (CCBITS | R15INTBITS | R15MODEBITS)); \ + ARMul_R15Altered (state); \ + } \ + } \ + while (0) + +#define SETABORT(i, m, d) \ + do \ + { \ + int SETABORT_mode = (m); \ + \ + ARMul_SetSPSR (state, SETABORT_mode, ARMul_GetCPSR (state)); \ + ARMul_SetCPSR (state, ((ARMul_GetCPSR (state) & ~(EMODE | TBIT)) \ + | (i) | SETABORT_mode)); \ + state->Reg[14] = temp - (d); \ + } \ + while (0) + +#ifndef MODE32 +#define VECTORS 0x20 +#define LEGALADDR 0x03ffffff +#define VECTORACCESS(address) (address < VECTORS && ARMul_MODE26BIT && state->prog32Sig) +#define ADDREXCEPT(address) (address > LEGALADDR && !state->data32Sig) +#endif + +#define INTERNALABORT(address) \ + do \ + { \ + if (address < VECTORS) \ + state->Aborted = ARMul_DataAbortV; \ + else \ + state->Aborted = ARMul_AddrExceptnV; \ + } \ + while (0) + +#ifdef MODE32 +#define TAKEABORT ARMul_Abort (state, ARMul_DataAbortV) +#else +#define TAKEABORT \ + do \ + { \ + if (state->Aborted == ARMul_AddrExceptnV) \ + ARMul_Abort (state, ARMul_AddrExceptnV); \ + else \ + ARMul_Abort (state, ARMul_DataAbortV); \ + } \ + while (0) +#endif + +#define CPTAKEABORT \ + do \ + { \ + if (!state->Aborted) \ + ARMul_Abort (state, ARMul_UndefinedInstrV); \ + else if (state->Aborted == ARMul_AddrExceptnV) \ + ARMul_Abort (state, ARMul_AddrExceptnV); \ + else \ + ARMul_Abort (state, ARMul_DataAbortV); \ + } \ + while (0); + + +/* Different ways to start the next instruction. */ +#define SEQ 0 +#define NONSEQ 1 +#define PCINCEDSEQ 2 +#define PCINCEDNONSEQ 3 +#define PRIMEPIPE 4 +#define RESUME 8 + +#define NORMALCYCLE state->NextInstr = 0 +#define BUSUSEDN state->NextInstr |= 1 /* The next fetch will be an N cycle. */ +#define BUSUSEDINCPCS \ + do \ + { \ + if (! state->is_v4) \ + { \ + /* A standard PC inc and an S cycle. */ \ + state->Reg[15] += isize; \ + state->NextInstr = (state->NextInstr & 0xff) | 2; \ + } \ + } \ + while (0) + +#define BUSUSEDINCPCN \ + do \ + { \ + if (state->is_v4) \ + BUSUSEDN; \ + else \ + { \ + /* A standard PC inc and an N cycle. */ \ + state->Reg[15] += isize; \ + state->NextInstr |= 3; \ + } \ + } \ + while (0) + +#define INCPC \ + do \ + { \ + /* A standard PC inc. */ \ + state->Reg[15] += isize; \ + state->NextInstr |= 2; \ + } \ + while (0) + +#define FLUSHPIPE state->NextInstr |= PRIMEPIPE + +/* Cycle based emulation. */ + +#define OUTPUTCP(i,a,b) +#define NCYCLE +#define SCYCLE +#define ICYCLE +#define CCYCLE +#define NEXTCYCLE(c) + +/* Macros to extract parts of instructions. */ +#define DESTReg (BITS (12, 15)) +#define LHSReg (BITS (16, 19)) +#define RHSReg (BITS ( 0, 3)) + +#define DEST (state->Reg[DESTReg]) + +#ifdef MODE32 +#ifdef MODET +#define LHS ((LHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC): (state->Reg[LHSReg])) +#else +#define LHS (state->Reg[LHSReg]) +#endif +#else +#define LHS ((LHSReg == 15) ? R15PC : (state->Reg[LHSReg])) +#endif + +#define MULDESTReg (BITS (16, 19)) +#define MULLHSReg (BITS ( 0, 3)) +#define MULRHSReg (BITS ( 8, 11)) +#define MULACCReg (BITS (12, 15)) + +#define DPImmRHS (ARMul_ImmedTable[BITS(0, 11)]) +#define DPSImmRHS temp = BITS(0,11) ; \ + rhs = ARMul_ImmedTable[temp] ; \ + if (temp > 255) /* There was a shift. */ \ + ASSIGNC (rhs >> 31) ; + +#ifdef MODE32 +#define DPRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \ + : GetDPRegRHS (state, instr)) +#define DPSRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \ + : GetDPSRegRHS (state, instr)) +#else +#define DPRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \ + : GetDPRegRHS (state, instr)) +#define DPSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \ + : GetDPSRegRHS (state, instr)) +#endif + +#define LSBase state->Reg[LHSReg] +#define LSImmRHS (BITS(0,11)) + +#ifdef MODE32 +#define LSRegRHS ((BITS (4, 11) == 0) ? state->Reg[RHSReg] \ + : GetLSRegRHS (state, instr)) +#else +#define LSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \ + : GetLSRegRHS (state, instr)) +#endif + +#define LSMNumRegs ((ARMword) ARMul_BitList[BITS (0, 7)] + \ + (ARMword) ARMul_BitList[BITS (8, 15)] ) +#define LSMBaseFirst ((LHSReg == 0 && BIT (0)) || \ + (BIT (LHSReg) && BITS (0, LHSReg - 1) == 0)) + +#define SWAPSRC (state->Reg[RHSReg]) + +#define LSCOff (BITS (0, 7) << 2) +#define CPNum BITS (8, 11) + +/* Determine if access to coprocessor CP is permitted. + The XScale has a register in CP15 which controls access to CP0 - CP13. */ +#define CP_ACCESS_ALLOWED(STATE, CP) \ + ( ((CP) >= 14) \ + || (! (STATE)->is_XScale) \ + || (read_cp15_reg (15, 0, 1) & (1 << (CP)))) + +/* Macro to rotate n right by b bits. */ +#define ROTATER(n, b) (((n) >> (b)) | ((n) << (32 - (b)))) + +/* Macros to store results of instructions. */ +#define WRITEDEST(d) \ + do \ + { \ + if (DESTReg == 15) \ + WriteR15 (state, d); \ + else \ + DEST = d; \ + } \ + while (0) + +#define WRITESDEST(d) \ + do \ + { \ + if (DESTReg == 15) \ + WriteSR15 (state, d); \ + else \ + { \ + DEST = d; \ + ARMul_NegZero (state, d); \ + } \ + } \ + while (0) + +#define WRITEDESTB(d) \ + do \ + { \ + if (DESTReg == 15) \ + WriteR15Branch (state, d); \ + else \ + DEST = d; \ + } \ + while (0) + +#define BYTETOBUS(data) ((data & 0xff) | \ + ((data & 0xff) << 8) | \ + ((data & 0xff) << 16) | \ + ((data & 0xff) << 24)) + +#define BUSTOBYTE(address, data) \ + do \ + { \ + if (state->bigendSig) \ + temp = (data >> (((address ^ 3) & 3) << 3)) & 0xff; \ + else \ + temp = (data >> ((address & 3) << 3)) & 0xff; \ + } \ + while (0) + +#define LOADMULT(instr, address, wb) LoadMult (state, instr, address, wb) +#define LOADSMULT(instr, address, wb) LoadSMult (state, instr, address, wb) +#define STOREMULT(instr, address, wb) StoreMult (state, instr, address, wb) +#define STORESMULT(instr, address, wb) StoreSMult (state, instr, address, wb) + +#define POSBRANCH ((instr & 0x7fffff) << 2) +#define NEGBRANCH ((0xff000000 |(instr & 0xffffff)) << 2) + + +/* Values for Emulate. */ +#define STOP 0 /* stop */ +#define CHANGEMODE 1 /* change mode */ +#define ONCE 2 /* execute just one interation */ +#define RUN 3 /* continuous execution */ + +/* Stuff that is shared across modes. */ +extern unsigned ARMul_MultTable[]; /* Number of I cycles for a mult. */ +extern ARMword ARMul_ImmedTable[]; /* Immediate DP LHS values. */ +extern char ARMul_BitList[]; /* Number of bits in a byte table. */ + +#define EVENTLISTSIZE 1024L + +/* Thumb support. */ +typedef enum +{ + t_undefined, /* Undefined Thumb instruction. */ + t_decoded, /* Instruction decoded to ARM equivalent. */ + t_branch /* Thumb branch (already processed). */ +} +tdstate; + +/* Macros to scrutinize instructions. */ +#define UNDEF_Test +#define UNDEF_Shift +#define UNDEF_MSRPC +#define UNDEF_MRSPC +#define UNDEF_MULPCDest +#define UNDEF_MULDestEQOp1 +#define UNDEF_LSRBPC +#define UNDEF_LSRBaseEQOffWb +#define UNDEF_LSRBaseEQDestWb +#define UNDEF_LSRPCBaseWb +#define UNDEF_LSRPCOffWb +#define UNDEF_LSMNoRegs +#define UNDEF_LSMPCBase +#define UNDEF_LSMUserBankWb +#define UNDEF_LSMBaseInListWb +#define UNDEF_SWPPC +#define UNDEF_CoProHS +#define UNDEF_MCRPC +#define UNDEF_LSCPCBaseWb +#define UNDEF_UndefNotBounced +#define UNDEF_ShortInt +#define UNDEF_IllegalMode +#define UNDEF_Prog32SigChange +#define UNDEF_Data32SigChange + +/* Prototypes for exported functions. */ +extern unsigned ARMul_NthReg (ARMword, unsigned); +extern int AddOverflow (ARMword, ARMword, ARMword); +extern int SubOverflow (ARMword, ARMword, ARMword); +extern ARMword ARMul_Emulate26 (ARMul_State *); +extern ARMword ARMul_Emulate32 (ARMul_State *); +extern unsigned IntPending (ARMul_State *); +extern void ARMul_CPSRAltered (ARMul_State *); +extern void ARMul_R15Altered (ARMul_State *); +extern ARMword ARMul_GetPC (ARMul_State *); +extern ARMword ARMul_GetNextPC (ARMul_State *); +extern ARMword ARMul_GetR15 (ARMul_State *); +extern ARMword ARMul_GetCPSR (ARMul_State *); +extern void ARMul_EnvokeEvent (ARMul_State *); +extern unsigned long ARMul_Time (ARMul_State *); +extern void ARMul_NegZero (ARMul_State *, ARMword); +extern void ARMul_SetPC (ARMul_State *, ARMword); +extern void ARMul_SetR15 (ARMul_State *, ARMword); +extern void ARMul_SetCPSR (ARMul_State *, ARMword); +extern ARMword ARMul_GetSPSR (ARMul_State *, ARMword); +extern void ARMul_Abort26 (ARMul_State *, ARMword); +extern void ARMul_Abort32 (ARMul_State *, ARMword); +extern ARMword ARMul_MRC (ARMul_State *, ARMword); +extern void ARMul_CDP (ARMul_State *, ARMword); +extern void ARMul_LDC (ARMul_State *, ARMword, ARMword); +extern void ARMul_STC (ARMul_State *, ARMword, ARMword); +extern void ARMul_MCR (ARMul_State *, ARMword, ARMword); +extern void ARMul_SetSPSR (ARMul_State *, ARMword, ARMword); +extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword); +extern ARMword ARMul_Align (ARMul_State *, ARMword, ARMword); +extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword); +extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword); +extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword); +extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword); +extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword); +extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword); +extern tdstate ARMul_ThumbDecode (ARMul_State *, ARMword, ARMword, ARMword *); +extern ARMword ARMul_GetReg (ARMul_State *, unsigned, unsigned); +extern void ARMul_SetReg (ARMul_State *, unsigned, unsigned, ARMword); +extern void ARMul_ScheduleEvent (ARMul_State *, unsigned long, unsigned (*) (ARMul_State *)); +/* Coprocessor support functions. */ +extern unsigned ARMul_CoProInit (ARMul_State *); +extern void ARMul_CoProExit (ARMul_State *); +extern void ARMul_CoProAttach (ARMul_State *, unsigned, ARMul_CPInits *, ARMul_CPExits *, + ARMul_LDCs *, ARMul_STCs *, ARMul_MRCs *, ARMul_MCRs *, + ARMul_CDPs *, ARMul_CPReads *, ARMul_CPWrites *); +extern void ARMul_CoProDetach (ARMul_State *, unsigned); +extern ARMword read_cp15_reg (unsigned, unsigned, unsigned); + +extern unsigned DSPLDC4 (ARMul_State *, unsigned, ARMword, ARMword); +extern unsigned DSPMCR4 (ARMul_State *, unsigned, ARMword, ARMword); +extern unsigned DSPMRC4 (ARMul_State *, unsigned, ARMword, ARMword *); +extern unsigned DSPSTC4 (ARMul_State *, unsigned, ARMword, ARMword *); +extern unsigned DSPCDP4 (ARMul_State *, unsigned, ARMword); +extern unsigned DSPMCR5 (ARMul_State *, unsigned, ARMword, ARMword); +extern unsigned DSPMRC5 (ARMul_State *, unsigned, ARMword, ARMword *); +extern unsigned DSPLDC5 (ARMul_State *, unsigned, ARMword, ARMword); +extern unsigned DSPSTC5 (ARMul_State *, unsigned, ARMword, ARMword *); +extern unsigned DSPCDP5 (ARMul_State *, unsigned, ARMword); +extern unsigned DSPMCR6 (ARMul_State *, unsigned, ARMword, ARMword); +extern unsigned DSPMRC6 (ARMul_State *, unsigned, ARMword, ARMword *); +extern unsigned DSPCDP6 (ARMul_State *, unsigned, ARMword);
armemu.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.