mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-25 21:19:54 +00:00
checkpoint
This commit is contained in:
parent
125d37c471
commit
1dc7c0ed84
@ -1,3 +1,179 @@
|
|||||||
|
Mon Nov 13 09:14:13 1995 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||||
|
|
||||||
|
* igen.c ({insn,model}_table_fields): Spell mnemonic correctly.
|
||||||
|
(gen_itable_h,itable_c_insn): Ditto.
|
||||||
|
(model support): Move model support around, add support for
|
||||||
|
model-data, model-internal. Use annex field for model-macros
|
||||||
|
now.
|
||||||
|
|
||||||
|
* configure.in (--enable-sim-inline): If --enable-sim-inline=no,
|
||||||
|
also define INLINE as nothing.
|
||||||
|
* configure: Regenerate.
|
||||||
|
|
||||||
|
* std-config.h (INLINE): Rather than nuking INLINE, only define it
|
||||||
|
as __inline__ if any of the INLINE flags are non-zero.
|
||||||
|
|
||||||
|
* options.c (print_options): Print out WITH_XOR_ENDAIN.
|
||||||
|
|
||||||
|
Mon Nov 13 23:03:45 1995 Andrew Cagney <cagneyhighland.com.au>
|
||||||
|
|
||||||
|
* ppc-instructions (rfi): Add missing code.
|
||||||
|
|
||||||
|
* cpu.c (cpu_get_time_base): Fix calculation of current value of
|
||||||
|
time base register.
|
||||||
|
|
||||||
|
* ppc-spr-table (TBL, TBU): Fix TBL/TBU entries - was confusing
|
||||||
|
m[tf]tb with m[tf]spr.
|
||||||
|
|
||||||
|
* ppc-instructions (mtspr, mfspr): Fix mttbl - wasn't storing
|
||||||
|
lower word.
|
||||||
|
|
||||||
|
Mon Nov 13 21:35:37 1995 Andrew Cagney <cagneyhighland.com.au>
|
||||||
|
|
||||||
|
* std-config.h (INLINE, STATIC_INLINE): Was being set to static
|
||||||
|
inline.. Only problem being that with ppc-opcode-simple this gave
|
||||||
|
it the chance to inline all the idecode functions with potentially
|
||||||
|
disasterous results on a 16mb PC. For moment hobble INLINE.
|
||||||
|
|
||||||
|
* configure.in, std-config.h (WITH_SMP): Make that 5 processors by
|
||||||
|
default ...
|
||||||
|
|
||||||
|
* configure.in: Tweek flags passed to gcc for --with-sim-warnings.
|
||||||
|
Firstly make them errors and secondly remove the options gcc-245
|
||||||
|
doesn't reconize.
|
||||||
|
|
||||||
|
Mon Nov 13 17:57:24 1995 Andrew Cagney <cagney@highland.com.au>
|
||||||
|
|
||||||
|
* misc.c (zalloc), cpu.c (cpu_init), devices
|
||||||
|
(console_io_read_buffer_callback, icu_io_read_buffer_callback,
|
||||||
|
vm_io_read_buffer_callback), main.c (zalloc), mon.c (memset),
|
||||||
|
sim_calls.c (zalloc) : replace bzero() with memset().
|
||||||
|
|
||||||
|
* emul_netbsd.c (write_direntries), psim.c (psim_read_register,
|
||||||
|
psim_write_register): replace bcopy() with memcpy().
|
||||||
|
|
||||||
|
Sun Nov 12 20:55:41 1995 Andrew Cagney <cagneyhighland.com.au>
|
||||||
|
|
||||||
|
* configure.in: for --disable-sim-inline (--enable-sim-inline=no),
|
||||||
|
force DEFAULT_INLINE to 0 rather then trusting the std
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
Sun Nov 12 20:55:41 1995 Andrew Cagney <cagneyhighland.com.au>
|
||||||
|
|
||||||
|
* igen.c (lf_print_idecode_table, idecode_table_leaf): Fix
|
||||||
|
generation of switch entries in tables - treat the same as
|
||||||
|
cracking/semantic functions.
|
||||||
|
|
||||||
|
* igen.c (idecode_switch_end, idecode_switch_leaf): Fix generation
|
||||||
|
of a boolean switch statement (field zero or non-zero).
|
||||||
|
|
||||||
|
* ppc-opcode-test-1, ppc-opcode-test-2: New files. These test the
|
||||||
|
switch/table generation ability of igen.
|
||||||
|
|
||||||
|
* igen.c (idecode_switch_leaf): Fix code output when a switch
|
||||||
|
statement needs to look up a table.
|
||||||
|
|
||||||
|
* igen.c (idecode_declare_if_switch): New function called from
|
||||||
|
gen_idecode_c - need to declare any idecode switch functions
|
||||||
|
before they are used in idecode tables.
|
||||||
|
|
||||||
|
* igen.c (lf_print_c_cracker_function, idecode_crack_leaf,
|
||||||
|
idecode_crack_insn): Add is_inline_function argument to code
|
||||||
|
printing cracker functions which indicates if STATIC_IDECODE or
|
||||||
|
STATIC_INLINE_IDECODE should be used for definition. For
|
||||||
|
idecode_crack_insn (which implies not duplicating/expanding) don't
|
||||||
|
declare function as inline - we assume that the only time this is
|
||||||
|
code is generated is when things are being tested. For
|
||||||
|
idecode_crack_leaf, make static (instead of INLINE) if the
|
||||||
|
instructions parent is a table as function will always be called
|
||||||
|
via a table.
|
||||||
|
|
||||||
|
* igen.c (idecode_expand_if_switch): Declare as STATIC_IDECODE not
|
||||||
|
STATIC_INLINE_IDECODE. Only the outermost idecode switch will be
|
||||||
|
called directly, all others are called via a table.
|
||||||
|
|
||||||
|
* igen.c (lf_print_semantic_function_header, semantics_h_leaf,
|
||||||
|
semantics_h_insn, semantics_h_function,
|
||||||
|
lf_print_c_semantic_function, semantics_c_function): Add
|
||||||
|
is_inline_function argument to lf_print_semantic_function_header
|
||||||
|
to indicate if an inline or static function declaration/definition
|
||||||
|
should be output. Depending on situtation call accordingly:
|
||||||
|
functions (not instruction semantic routines) are always inline;
|
||||||
|
Semantic routines are made inline when there is no icache (cache
|
||||||
|
will contain the function address) and are duplicating (see above)
|
||||||
|
and the parent of the instruction is a switch statement.
|
||||||
|
|
||||||
|
* igen.c (opcode_field_new): Delete. Code changed to use ZALLOC
|
||||||
|
and moved to insn_table_find_opcode_field.
|
||||||
|
|
||||||
|
* table.c (table_open): Fix typo (nr_model_fields vs nr_fields).
|
||||||
|
|
||||||
|
* igen.c (model_c_insn): Suggestion - document the name of the
|
||||||
|
instruction on each line of the instruction model table.
|
||||||
|
|
||||||
|
Fri Nov 10 00:44:38 1995 Andrew Cagney <cagneyhighland.com.au>
|
||||||
|
|
||||||
|
* emul_netbsd.c (do_ioctl): Cleanup compilation.
|
||||||
|
|
||||||
|
* sim_callbacks.h (__attribute__): Only define if not defined (was
|
||||||
|
already defined on NetBSD host).
|
||||||
|
|
||||||
|
Wed Nov 8 21:49:52 1995 Andrew Cagney <cagneyhighland.com.au>
|
||||||
|
|
||||||
|
* std-config.h (WITH_XOR_ENDIAN), configure.in, Makefile.in: New
|
||||||
|
macro, indicates if the PowerPC's horrible XOR endian mode should
|
||||||
|
be suported. Add to configure and make.
|
||||||
|
|
||||||
|
* vm_n.h (vm_data_map_read_N, vm_data_map_write_N), vm.c
|
||||||
|
(vm_instruction_map_read): If XOR endian, xor the address
|
||||||
|
with a value from an xor table (indexed by size of access).
|
||||||
|
|
||||||
|
* vm.c (vm_synchronize_context), cpu.c (cpu_synchronize_context):
|
||||||
|
set up xor table to xor if there is a conflict between the
|
||||||
|
CURRENT_TARGET_ENDIAN and the endian indicated in the MSR. Move
|
||||||
|
check of suported change of endian mode from cpu.c to vm.c.
|
||||||
|
|
||||||
|
* vm.c (vm_data_map_write_buffer, vm_data_map_read_buffer):
|
||||||
|
Hopefully added correct hack to handle XOR endian mode.
|
||||||
|
|
||||||
|
FIXME: If NONSTRICT alignment and XOR ENDIAN and MSR indicates
|
||||||
|
little endian mode, the model accepts miss aligned transfers.
|
||||||
|
|
||||||
|
FIXME: Need to create an `init' device that, during
|
||||||
|
initializatioin for XOR mode, it mushes (XOR address) all the dma
|
||||||
|
data before passing it on to the core for storage. Just like the
|
||||||
|
real thing really.
|
||||||
|
|
||||||
|
Wed Nov 8 21:49:52 1995 Andrew Cagney <cagneyhighland.com.au>
|
||||||
|
|
||||||
|
* devices.c (halt_io_write_buffer_callback): Use value written to
|
||||||
|
halt device to determine exit status. Thus allowing
|
||||||
|
success/failure of OEA tests.
|
||||||
|
|
||||||
|
Wed Nov 8 00:10:38 1995 Andrew Cagney <cagneyhighland.com.au>
|
||||||
|
|
||||||
|
* ppc-instructions (icbi): If icache present flush it.
|
||||||
|
|
||||||
|
Tue Nov 7 23:36:31 1995 Andrew Cagney <cagneyhighland.com.au>
|
||||||
|
|
||||||
|
* devices.c (htab_init_callback): Add code to create htab/pte.
|
||||||
|
|
||||||
|
* devices.c (dma_file, file_init_callback, htab_init_callback):
|
||||||
|
New function - Dma the named file into memory at the specified
|
||||||
|
address. Use.
|
||||||
|
|
||||||
|
* device_tree.h, device_tree.c (scand_*): New functions.
|
||||||
|
|
||||||
|
Tue Nov 7 23:36:31 1995 Andrew Cagney <cagneyhighland.com.au>
|
||||||
|
|
||||||
|
* filter_filename.c, Makefile.in: Change so that only dependant on
|
||||||
|
a very limited nr of files. Stops an unnecessary dependency.
|
||||||
|
|
||||||
|
Tue Nov 7 15:44:33 1995 Andrew Cagney <cagney@highland.com.au>
|
||||||
|
|
||||||
|
* core.c (core_map_find_mapping): Use cpu_halt rather than error
|
||||||
|
to abort an access to an undefined address.
|
||||||
|
|
||||||
Sun Nov 12 07:58:09 1995 Michael Meissner <meissner@tiktok.cygnus.com>
|
Sun Nov 12 07:58:09 1995 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||||
|
|
||||||
* igen.c (model_table_insert_{macro,function}): New functions.
|
* igen.c (model_table_insert_{macro,function}): New functions.
|
||||||
@ -439,7 +615,7 @@ Thu Nov 2 08:54:04 1995 Michael Meissner <meissner@tiktok.cygnus.com>
|
|||||||
* configure.in: Add support for --enable-sim-opcode=stupid.
|
* configure.in: Add support for --enable-sim-opcode=stupid.
|
||||||
* configure: Regenerate.
|
* configure: Regenerate.
|
||||||
|
|
||||||
Wed Nov 1 23:46:59 1995 Andrew Cagney - aka Noid <cagney@highland.com.au>
|
Wed Nov 1 23:46:59 1995 Andrew Cagney <cagney@highland.com.au>
|
||||||
|
|
||||||
* std-config (INLINE_DEVICE_TREE): Don't inline either of
|
* std-config (INLINE_DEVICE_TREE): Don't inline either of
|
||||||
device_tree.c or devices.c. There is no significant gain.
|
device_tree.c or devices.c. There is no significant gain.
|
||||||
@ -447,7 +623,7 @@ Wed Nov 1 23:46:59 1995 Andrew Cagney - aka Noid <cagney@highland.com.au>
|
|||||||
* configure.in, Makefile.in: add --enable-sim-icache=[0-9]* and
|
* configure.in, Makefile.in: add --enable-sim-icache=[0-9]* and
|
||||||
IGEN_ICACHE macro.
|
IGEN_ICACHE macro.
|
||||||
|
|
||||||
Wed Nov 1 23:46:59 1995 Andrew Cagney - aka Noid <cagney@highland.com.au>
|
Wed Nov 1 23:46:59 1995 Andrew Cagney <cagney@highland.com.au>
|
||||||
|
|
||||||
* igen.c (main), misc.h (target_a2i, i2target), misc.c: Add
|
* igen.c (main), misc.h (target_a2i, i2target), misc.c: Add
|
||||||
functions to convert between target and igen internal bit numbers.
|
functions to convert between target and igen internal bit numbers.
|
||||||
@ -455,17 +631,17 @@ Wed Nov 1 23:46:59 1995 Andrew Cagney - aka Noid <cagney@highland.com.au>
|
|||||||
bit nr) options to igen. Typical usage would be: ./igen -b 16 -h
|
bit nr) options to igen. Typical usage would be: ./igen -b 16 -h
|
||||||
15 for a 16 bit instruction format with the msb given a number 15.
|
15 for a 16 bit instruction format with the msb given a number 15.
|
||||||
|
|
||||||
Wed Nov 1 22:17:32 1995 Andrew Cagney - aka Noid <cagney@highland.com.au>
|
Wed Nov 1 22:17:32 1995 Andrew Cagney <cagney@highland.com.au>
|
||||||
|
|
||||||
* dgen.c (main): Was outputting optarg even when it was NULL.
|
* dgen.c (main): Was outputting optarg even when it was NULL.
|
||||||
|
|
||||||
Tue Oct 31 23:48:33 1995 Andrew Cagney - aka Noid <cagney@highland.com.au>
|
Tue Oct 31 23:48:33 1995 Andrew Cagney <cagney@highland.com.au>
|
||||||
|
|
||||||
* vm_n.h (vm_data_map_load_N, vm_data_map_store_n), debug.h,
|
* vm_n.h (vm_data_map_load_N, vm_data_map_store_n), debug.h,
|
||||||
debug.c: Add tracing of load/store unit (virtual) with -t
|
debug.c: Add tracing of load/store unit (virtual) with -t
|
||||||
load-store.
|
load-store.
|
||||||
|
|
||||||
Tue Oct 31 21:44:01 1995 Andrew Cagney - aka Noid <cagney@highland.com.au>
|
Tue Oct 31 21:44:01 1995 Andrew Cagney <cagney@highland.com.au>
|
||||||
|
|
||||||
* std-config.h (WITH_ENVIRONMENT): Add USER_ENVIRONMENT which does
|
* std-config.h (WITH_ENVIRONMENT): Add USER_ENVIRONMENT which does
|
||||||
not include things such as the time base and events.
|
not include things such as the time base and events.
|
||||||
@ -477,7 +653,7 @@ Tue Oct 31 21:44:01 1995 Andrew Cagney - aka Noid <cagney@highland.com.au>
|
|||||||
/options/environment-architecture with values user, virtual and
|
/options/environment-architecture with values user, virtual and
|
||||||
operating.
|
operating.
|
||||||
|
|
||||||
Tue Oct 31 21:31:32 1995 Andrew Cagney - aka Noid <cagney@highland.com.au>
|
Tue Oct 31 21:31:32 1995 Andrew Cagney <cagney@highland.com.au>
|
||||||
|
|
||||||
* ppc-opcode-stupid: Third example of use of opcode table - this
|
* ppc-opcode-stupid: Third example of use of opcode table - this
|
||||||
one expands all mtspr/mfspr and branch instructions. Appears to
|
one expands all mtspr/mfspr and branch instructions. Appears to
|
||||||
|
@ -72,6 +72,7 @@ BSWAP_CFLAGS = @sim_bswap@
|
|||||||
ENDIAN_CFLAGS = @sim_endian@
|
ENDIAN_CFLAGS = @sim_endian@
|
||||||
HOSTENDIAN_CFLAGS = @sim_hostendian@
|
HOSTENDIAN_CFLAGS = @sim_hostendian@
|
||||||
SMP_CFLAGS = @sim_smp@
|
SMP_CFLAGS = @sim_smp@
|
||||||
|
XOR_ENDIAN_CFLAGS = @sim_xor_endian@
|
||||||
BITSIZE_CFLAGS = @sim_bitsize@
|
BITSIZE_CFLAGS = @sim_bitsize@
|
||||||
HOSTBITSIZE_CFLAGS = @sim_hostbitsize@
|
HOSTBITSIZE_CFLAGS = @sim_hostbitsize@
|
||||||
ENV_CFLAGS = @sim_env@
|
ENV_CFLAGS = @sim_env@
|
||||||
@ -89,6 +90,7 @@ CONFIG_CFLAGS = $(BSWAP_CFLAGS) \
|
|||||||
$(ENDIAN_CFLAGS) \
|
$(ENDIAN_CFLAGS) \
|
||||||
$(HOSTENDIAN_CFLAGS) \
|
$(HOSTENDIAN_CFLAGS) \
|
||||||
$(SMP_CFLAGS) \
|
$(SMP_CFLAGS) \
|
||||||
|
$(XOR_ENDIAN_CFLAGS) \
|
||||||
$(BITSIZE_CFLAGS) \
|
$(BITSIZE_CFLAGS) \
|
||||||
$(HOSTBITSIZE_CFLAGS) \
|
$(HOSTBITSIZE_CFLAGS) \
|
||||||
$(ENV_CFLAGS) \
|
$(ENV_CFLAGS) \
|
||||||
@ -281,7 +283,7 @@ psim.o: psim.c psim.h $(CPU_H) $(IDECODE_H) $(INLINE) $(LIB_SRC) $(BUILT_SRC)
|
|||||||
bits.o: bits.c $(BASICS_H)
|
bits.o: bits.c $(BASICS_H)
|
||||||
|
|
||||||
debug.o: debug.c $(BASICS_H)
|
debug.o: debug.c $(BASICS_H)
|
||||||
filter_filename.o: filter_filename.c config.h ppc-config.h
|
filter_filename.o: filter_filename.c filter_filename.h config.h ppc-config.h
|
||||||
|
|
||||||
sim-endian.o: sim-endian.c sim-endian-n.h $(BASICS_H)
|
sim-endian.o: sim-endian.c sim-endian-n.h $(BASICS_H)
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ fi],[sim_cflags=""])dnl
|
|||||||
AC_ARG_ENABLE(sim-warnings,
|
AC_ARG_ENABLE(sim-warnings,
|
||||||
[ --enable-sim-warnings=opts Extra CFLAGS for turning on compiler warnings except for idecode.o, semantics.o and psim.o],
|
[ --enable-sim-warnings=opts Extra CFLAGS for turning on compiler warnings except for idecode.o, semantics.o and psim.o],
|
||||||
[case "${enableval}" in
|
[case "${enableval}" in
|
||||||
yes) sim_warnings="-Wall -Wpointer-arith -Wbad-function-cast -Wmissing-prototypes -Wmissing-declarations";;
|
yes) sim_warnings="-Werror -Wall -Wpointer-arith -Wmissing-prototypes";;
|
||||||
no) sim_warnings="-w";;
|
no) sim_warnings="-w";;
|
||||||
*) sim_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
|
*) sim_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
|
||||||
esac
|
esac
|
||||||
@ -125,7 +125,7 @@ AC_ARG_ENABLE(sim-inline,
|
|||||||
[ --enable-sim-inline=inlines Specify which functions should be inlined.],
|
[ --enable-sim-inline=inlines Specify which functions should be inlined.],
|
||||||
[sim_inline=""
|
[sim_inline=""
|
||||||
case "$enableval" in
|
case "$enableval" in
|
||||||
no) sim_inline="";;
|
no) sim_inline="-DDEFAULT_INLINE=0 -DINLINE=";;
|
||||||
0) sim_inline="-DDEFAULT_INLINE=0";;
|
0) sim_inline="-DDEFAULT_INLINE=0";;
|
||||||
yes | 2) sim_inline="-DDEFAULT_INLINE=2";;
|
yes | 2) sim_inline="-DDEFAULT_INLINE=2";;
|
||||||
1) sim_inline="-DDEFAULT_INLINE=1";;
|
1) sim_inline="-DDEFAULT_INLINE=1";;
|
||||||
@ -198,7 +198,7 @@ fi],[sim_hostendian=""])dnl
|
|||||||
AC_ARG_ENABLE(sim-smp,
|
AC_ARG_ENABLE(sim-smp,
|
||||||
[ --enable-sim-smp=n Specify number of processors to configure for.],
|
[ --enable-sim-smp=n Specify number of processors to configure for.],
|
||||||
[case "${enableval}" in
|
[case "${enableval}" in
|
||||||
yes) sim_smp="-DWITH_SMP=2";;
|
yes) sim_smp="-DWITH_SMP=5";;
|
||||||
no) sim_smp="-DWITH_SMP=0";;
|
no) sim_smp="-DWITH_SMP=0";;
|
||||||
*) sim_smp="-DWITH_SMP=$enableval";;
|
*) sim_smp="-DWITH_SMP=$enableval";;
|
||||||
esac
|
esac
|
||||||
@ -209,6 +209,14 @@ if test x"$silent" != x"yes"; then
|
|||||||
echo "Setting smp flags = $sim_smp" 6>&1
|
echo "Setting smp flags = $sim_smp" 6>&1
|
||||||
fi])dnl
|
fi])dnl
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(sim-xor-endian,
|
||||||
|
[ --enable-sim-xor-endian=n Specify number bytes involved in PowerPC XOR bi-endian mode (default 8).],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes) sim_xor_endian="-DWITH_XOR_ENDIAN=8";;
|
||||||
|
no) sim_xor_endian="-DWITH_XOR_ENDIAN=0";;
|
||||||
|
*) sim_xor_endian="-DWITH_XOR_ENDIAN=$enableval";;
|
||||||
|
esac],[sim_xor_endian=""])dnl
|
||||||
|
|
||||||
AC_ARG_ENABLE(sim-bitsize,
|
AC_ARG_ENABLE(sim-bitsize,
|
||||||
[ --enable-sim-bitsize=n Specify target bitsize (32 or 64).],
|
[ --enable-sim-bitsize=n Specify target bitsize (32 or 64).],
|
||||||
[case "${enableval}" in
|
[case "${enableval}" in
|
||||||
@ -377,6 +385,7 @@ AC_SUBST(sim_icache)
|
|||||||
AC_SUBST(sim_inline)
|
AC_SUBST(sim_inline)
|
||||||
AC_SUBST(sim_bswap)
|
AC_SUBST(sim_bswap)
|
||||||
AC_SUBST(sim_endian)
|
AC_SUBST(sim_endian)
|
||||||
|
AC_SUBST(sim_xor_endian)
|
||||||
AC_SUBST(sim_hostendian)
|
AC_SUBST(sim_hostendian)
|
||||||
AC_SUBST(sim_smp)
|
AC_SUBST(sim_smp)
|
||||||
AC_SUBST(sim_bitsize)
|
AC_SUBST(sim_bitsize)
|
||||||
|
@ -464,43 +464,49 @@ device_tree_dump(device_tree *device,
|
|||||||
|
|
||||||
/* Parse a device name, various formats */
|
/* Parse a device name, various formats */
|
||||||
|
|
||||||
#define SCAN_INIT(START, END, COUNT, NAME) \
|
#define SCAN_INIT(NAME) \
|
||||||
char *START = NULL; \
|
char *START = (char*)0; \
|
||||||
char *END = strchr(NAME, '@'); \
|
char *END = (char*)0; \
|
||||||
int COUNT = 0; \
|
int COUNT = -1; \
|
||||||
if (END == NULL) \
|
/* find the first element */ \
|
||||||
return 0; \
|
END = strchr(NAME, '@'); \
|
||||||
|
if (END == (char*)0) \
|
||||||
|
return COUNT; \
|
||||||
|
COUNT += 1; \
|
||||||
START = END + 1
|
START = END + 1
|
||||||
|
|
||||||
#define SCAN_U(START, END, COUNT, U) \
|
#define SCAN_END \
|
||||||
|
return COUNT
|
||||||
|
|
||||||
|
#define SCAN_U(U) \
|
||||||
do { \
|
do { \
|
||||||
*U = strtoul(START, &END, 0); \
|
*U = strtoul(START, &END, 0); \
|
||||||
if (START == END) \
|
if (START == END) \
|
||||||
return COUNT; \
|
return COUNT; \
|
||||||
COUNT++; \
|
COUNT += 1; \
|
||||||
if (*END != ',') \
|
if (*END != ',') \
|
||||||
return COUNT; \
|
return COUNT; \
|
||||||
START = END + 1; \
|
START = END + 1; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SCAN_P(START, END, COUNT, P) \
|
#define SCAN_P(P) \
|
||||||
do { \
|
do { \
|
||||||
*P = (void*)(unsigned)strtouq(START, &END, 0); \
|
*P = (void*)(unsigned)strtouq(START, END, 0); \
|
||||||
if (START == END) \
|
if (START == END) \
|
||||||
return COUNT; \
|
return COUNT; \
|
||||||
COUNT++; \
|
COUNT += 1; \
|
||||||
if (*END != ',') \
|
if (*END != ',') \
|
||||||
return COUNT; \
|
return COUNT; \
|
||||||
START = END + 1; \
|
START = END + 1; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SCAN_C(START, END, COUNT, C, SIZE) \
|
#define SCAN_C(C, SIZE) \
|
||||||
do { \
|
do { \
|
||||||
char *chp = C; \
|
char *chp = C; \
|
||||||
END = START; \
|
END = START; \
|
||||||
while (*END != '\0' && *END != ',') { \
|
while (*END != '\0' && *END != ',') { \
|
||||||
if (*END == '\\') \
|
if (*END == '\\') \
|
||||||
END++; \
|
END += 1; \
|
||||||
*chp = *END; \
|
*chp = *END; \
|
||||||
chp += 1; \
|
chp += 1; \
|
||||||
END += 1; \
|
END += 1; \
|
||||||
@ -510,19 +516,55 @@ do { \
|
|||||||
*chp = '\0'; \
|
*chp = '\0'; \
|
||||||
if (START == END) \
|
if (START == END) \
|
||||||
return COUNT; \
|
return COUNT; \
|
||||||
COUNT++; \
|
COUNT += 1; \
|
||||||
if (*END != ',') \
|
if (*END != ',') \
|
||||||
return COUNT; \
|
return COUNT; \
|
||||||
START = END + 1; \
|
START = END + 1; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE int
|
||||||
|
scand_c(const char *name,
|
||||||
|
char *c1,
|
||||||
|
unsigned c1size)
|
||||||
|
{
|
||||||
|
SCAN_INIT(name);
|
||||||
|
SCAN_C(c1, c1size);
|
||||||
|
SCAN_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE int
|
||||||
|
scand_c_uw_u(const char *name,
|
||||||
|
char *c1,
|
||||||
|
unsigned c1size,
|
||||||
|
unsigned_word *uw2,
|
||||||
|
unsigned *u3)
|
||||||
|
{
|
||||||
|
SCAN_INIT(name);
|
||||||
|
SCAN_C(c1, c1size);
|
||||||
|
SCAN_U(uw2);
|
||||||
|
SCAN_U(u3);
|
||||||
|
SCAN_END;
|
||||||
|
}
|
||||||
|
|
||||||
INLINE_DEVICE_TREE int
|
INLINE_DEVICE_TREE int
|
||||||
scand_uw(const char *name,
|
scand_uw(const char *name,
|
||||||
unsigned_word *uw1)
|
unsigned_word *uw1)
|
||||||
{
|
{
|
||||||
SCAN_INIT(start, end, count, name);
|
SCAN_INIT(name);
|
||||||
SCAN_U(start, end, count, uw1);
|
SCAN_U(uw1);
|
||||||
return count;
|
SCAN_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE int
|
||||||
|
scand_uw_c(const char *name,
|
||||||
|
unsigned_word *uw1,
|
||||||
|
char *c2,
|
||||||
|
unsigned c2size)
|
||||||
|
{
|
||||||
|
SCAN_INIT(name);
|
||||||
|
SCAN_U(uw1);
|
||||||
|
SCAN_C(c2, c2size);
|
||||||
|
SCAN_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE_DEVICE_TREE int
|
INLINE_DEVICE_TREE int
|
||||||
@ -530,10 +572,10 @@ scand_uw_u(const char *name,
|
|||||||
unsigned_word *uw1,
|
unsigned_word *uw1,
|
||||||
unsigned *u2)
|
unsigned *u2)
|
||||||
{
|
{
|
||||||
SCAN_INIT(start, end, count, name);
|
SCAN_INIT(name);
|
||||||
SCAN_U(start, end, count, uw1);
|
SCAN_U(uw1);
|
||||||
SCAN_U(start, end, count, u2);
|
SCAN_U(u2);
|
||||||
return count;
|
SCAN_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE_DEVICE_TREE int
|
INLINE_DEVICE_TREE int
|
||||||
@ -542,11 +584,22 @@ scand_uw_u_u(const char *name,
|
|||||||
unsigned *u2,
|
unsigned *u2,
|
||||||
unsigned *u3)
|
unsigned *u3)
|
||||||
{
|
{
|
||||||
SCAN_INIT(start, end, count, name);
|
SCAN_INIT(name);
|
||||||
SCAN_U(start, end, count, uw1);
|
SCAN_U(uw1);
|
||||||
SCAN_U(start, end, count, u2);
|
SCAN_U(u2);
|
||||||
SCAN_U(start, end, count, u3);
|
SCAN_U(u3);
|
||||||
return count;
|
SCAN_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE int
|
||||||
|
scand_uw_uw(const char *name,
|
||||||
|
unsigned_word *uw1,
|
||||||
|
unsigned_word *uw2)
|
||||||
|
{
|
||||||
|
SCAN_INIT(name);
|
||||||
|
SCAN_U(uw1);
|
||||||
|
SCAN_U(uw2);
|
||||||
|
SCAN_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE_DEVICE_TREE int
|
INLINE_DEVICE_TREE int
|
||||||
@ -555,33 +608,46 @@ scand_uw_uw_u(const char *name,
|
|||||||
unsigned_word *uw2,
|
unsigned_word *uw2,
|
||||||
unsigned *u3)
|
unsigned *u3)
|
||||||
{
|
{
|
||||||
SCAN_INIT(start, end, count, name);
|
SCAN_INIT(name);
|
||||||
SCAN_U(start, end, count, uw1);
|
SCAN_U(uw1);
|
||||||
SCAN_U(start, end, count, uw2);
|
SCAN_U(uw2);
|
||||||
SCAN_U(start, end, count, u3);
|
SCAN_U(u3);
|
||||||
return count;
|
SCAN_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE_DEVICE_TREE int
|
INLINE_DEVICE_TREE int
|
||||||
scand_c(const char *name,
|
scand_uw_uw_u_u_c(const char *name,
|
||||||
char *c1, int c1size)
|
unsigned_word *uw1,
|
||||||
|
unsigned_word *uw2,
|
||||||
|
unsigned *u3,
|
||||||
|
unsigned *u4,
|
||||||
|
char *c5,
|
||||||
|
unsigned c5size)
|
||||||
{
|
{
|
||||||
SCAN_INIT(start, end, count, name);
|
SCAN_INIT(name);
|
||||||
SCAN_C(start, end, count, c1, c1size);
|
SCAN_U(uw1);
|
||||||
return count;
|
SCAN_U(uw2);
|
||||||
|
SCAN_U(u3);
|
||||||
|
SCAN_U(u4);
|
||||||
|
SCAN_C(c5, c5size);
|
||||||
|
SCAN_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE_DEVICE_TREE int
|
INLINE_DEVICE_TREE int
|
||||||
scand_c_uw_u(const char *name,
|
scand_uw_uw_u_u_u(const char *name,
|
||||||
char *c1, int c1size,
|
unsigned_word *uw1,
|
||||||
unsigned_word *uw2,
|
unsigned_word *uw2,
|
||||||
unsigned *u3)
|
unsigned *u3,
|
||||||
|
unsigned *u4,
|
||||||
|
unsigned *u5)
|
||||||
{
|
{
|
||||||
SCAN_INIT(start, end, count, name);
|
SCAN_INIT(name);
|
||||||
SCAN_C(start, end, count, c1, c1size);
|
SCAN_U(uw1);
|
||||||
SCAN_U(start, end, count, uw2);
|
SCAN_U(uw2);
|
||||||
SCAN_U(start, end, count, u3);
|
SCAN_U(u3);
|
||||||
return count;
|
SCAN_U(u4);
|
||||||
|
SCAN_U(u5);
|
||||||
|
SCAN_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -633,6 +699,43 @@ enum {
|
|||||||
strlen_unsigned_word = 18,
|
strlen_unsigned_word = 18,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE char *
|
||||||
|
printd_c(const char *name,
|
||||||
|
const char *c1)
|
||||||
|
{
|
||||||
|
int sizeof_buf = (strlen(name)
|
||||||
|
+ strlen("@")
|
||||||
|
+ c_strlen(c1)
|
||||||
|
+ 1);
|
||||||
|
char *buf = (char*)zalloc(sizeof_buf);
|
||||||
|
strcpy(buf, name);
|
||||||
|
strcat(buf, "@");
|
||||||
|
c_strcat(buf, c1);
|
||||||
|
ASSERT(strlen(buf) < sizeof_buf);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE char *
|
||||||
|
printd_c_uw(const char *name,
|
||||||
|
const char *c1,
|
||||||
|
unsigned_word uw2)
|
||||||
|
{
|
||||||
|
int sizeof_buf = (strlen(name)
|
||||||
|
+ strlen("@")
|
||||||
|
+ c_strlen(c1)
|
||||||
|
+ strlen(",")
|
||||||
|
+ strlen_unsigned_word
|
||||||
|
+ 1);
|
||||||
|
char *buf = (char*)zalloc(sizeof_buf);
|
||||||
|
strcpy(buf, name);
|
||||||
|
strcat(buf, "@");
|
||||||
|
c_strcat(buf, c1);
|
||||||
|
strcat(buf, ",");
|
||||||
|
u_strcat(buf, uw2);
|
||||||
|
ASSERT(strlen(buf) < sizeof_buf);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
INLINE_DEVICE_TREE char *
|
INLINE_DEVICE_TREE char *
|
||||||
printd_uw_u(const char *name,
|
printd_uw_u(const char *name,
|
||||||
unsigned_word uw1,
|
unsigned_word uw1,
|
||||||
@ -711,41 +814,4 @@ printd_uw_u_u_c(const char *name,
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE_DEVICE_TREE char *
|
|
||||||
printd_c(const char *name,
|
|
||||||
const char *c1)
|
|
||||||
{
|
|
||||||
int sizeof_buf = (strlen(name)
|
|
||||||
+ strlen("@")
|
|
||||||
+ c_strlen(c1)
|
|
||||||
+ 1);
|
|
||||||
char *buf = (char*)zalloc(sizeof_buf);
|
|
||||||
strcpy(buf, name);
|
|
||||||
strcat(buf, "@");
|
|
||||||
c_strcat(buf, c1);
|
|
||||||
ASSERT(strlen(buf) < sizeof_buf);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
INLINE_DEVICE_TREE char *
|
|
||||||
printd_c_uw(const char *name,
|
|
||||||
const char *c1,
|
|
||||||
unsigned_word uw2)
|
|
||||||
{
|
|
||||||
int sizeof_buf = (strlen(name)
|
|
||||||
+ strlen("@")
|
|
||||||
+ c_strlen(c1)
|
|
||||||
+ strlen(",")
|
|
||||||
+ strlen_unsigned_word
|
|
||||||
+ 1);
|
|
||||||
char *buf = (char*)zalloc(sizeof_buf);
|
|
||||||
strcpy(buf, name);
|
|
||||||
strcat(buf, "@");
|
|
||||||
c_strcat(buf, c1);
|
|
||||||
strcat(buf, ",");
|
|
||||||
u_strcat(buf, uw2);
|
|
||||||
ASSERT(strlen(buf) < sizeof_buf);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _DEVICE_TREE_C_ */
|
#endif /* _DEVICE_TREE_C_ */
|
||||||
|
@ -116,10 +116,28 @@ INLINE_DEVICE_TREE void device_tree_dump
|
|||||||
u: unsigned
|
u: unsigned
|
||||||
c: string */
|
c: string */
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE int scand_c
|
||||||
|
(const char *name,
|
||||||
|
char *c1,
|
||||||
|
unsigned c1size);
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE int scand_c_uw_u
|
||||||
|
(const char *name,
|
||||||
|
char *c1,
|
||||||
|
unsigned c1size,
|
||||||
|
unsigned_word *uw2,
|
||||||
|
unsigned *u3);
|
||||||
|
|
||||||
INLINE_DEVICE_TREE int scand_uw
|
INLINE_DEVICE_TREE int scand_uw
|
||||||
(const char *name,
|
(const char *name,
|
||||||
unsigned_word *uw1);
|
unsigned_word *uw1);
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE int scand_uw_c
|
||||||
|
(const char *name,
|
||||||
|
unsigned_word *uw1,
|
||||||
|
char *c2,
|
||||||
|
unsigned c2size);
|
||||||
|
|
||||||
INLINE_DEVICE_TREE int scand_uw_u
|
INLINE_DEVICE_TREE int scand_uw_u
|
||||||
(const char *name,
|
(const char *name,
|
||||||
unsigned_word *uw1,
|
unsigned_word *uw1,
|
||||||
@ -131,21 +149,42 @@ INLINE_DEVICE_TREE int scand_uw_u_u
|
|||||||
unsigned *u2,
|
unsigned *u2,
|
||||||
unsigned *u3);
|
unsigned *u3);
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE int scand_uw_uw
|
||||||
|
(const char *name,
|
||||||
|
unsigned_word *uw1,
|
||||||
|
unsigned_word *uw2);
|
||||||
|
|
||||||
INLINE_DEVICE_TREE int scand_uw_uw_u
|
INLINE_DEVICE_TREE int scand_uw_uw_u
|
||||||
(const char *name,
|
(const char *name,
|
||||||
unsigned_word *uw1,
|
unsigned_word *uw1,
|
||||||
unsigned_word *uw2,
|
unsigned_word *uw2,
|
||||||
unsigned *u3);
|
unsigned *u3);
|
||||||
|
|
||||||
INLINE_DEVICE_TREE int scand_c
|
INLINE_DEVICE_TREE int scand_uw_uw_u_u_c
|
||||||
(const char *name,
|
(const char *name,
|
||||||
char *c1, int c1size);
|
unsigned_word *uw1,
|
||||||
|
|
||||||
INLINE_DEVICE_TREE int scand_c_uw_u
|
|
||||||
(const char *name,
|
|
||||||
char *c1, int c1size,
|
|
||||||
unsigned_word *uw2,
|
unsigned_word *uw2,
|
||||||
unsigned *u3);
|
unsigned *u3,
|
||||||
|
unsigned *u4,
|
||||||
|
char *c5,
|
||||||
|
unsigned c5size);
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE int scand_uw_uw_u_u_u
|
||||||
|
(const char *name,
|
||||||
|
unsigned_word *uw1,
|
||||||
|
unsigned_word *uw2,
|
||||||
|
unsigned *u3,
|
||||||
|
unsigned *u4,
|
||||||
|
unsigned *u5);
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE char *printd_c
|
||||||
|
(const char *name,
|
||||||
|
const char *c1);
|
||||||
|
|
||||||
|
INLINE_DEVICE_TREE char *printd_c_uw
|
||||||
|
(const char *name,
|
||||||
|
const char *c1,
|
||||||
|
unsigned_word uw2);
|
||||||
|
|
||||||
INLINE_DEVICE_TREE char *printd_uw_u
|
INLINE_DEVICE_TREE char *printd_uw_u
|
||||||
(const char *name,
|
(const char *name,
|
||||||
@ -165,13 +204,4 @@ INLINE_DEVICE_TREE char *printd_uw_u_u_c
|
|||||||
unsigned u3,
|
unsigned u3,
|
||||||
const char *c4);
|
const char *c4);
|
||||||
|
|
||||||
INLINE_DEVICE_TREE char *printd_c
|
|
||||||
(const char *name,
|
|
||||||
const char *c1);
|
|
||||||
|
|
||||||
INLINE_DEVICE_TREE char *printd_c_uw
|
|
||||||
(const char *name,
|
|
||||||
const char *c1,
|
|
||||||
unsigned_word uw2);
|
|
||||||
|
|
||||||
#endif /* _DEVICE_TREE_H_ */
|
#endif /* _DEVICE_TREE_H_ */
|
||||||
|
@ -80,6 +80,47 @@ generic_init_callback(const device *me,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* DMA a file into memory */
|
||||||
|
STATIC_INLINE_DEVICES int
|
||||||
|
dma_file(const device *me,
|
||||||
|
const char *file_name,
|
||||||
|
unsigned_word addr)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
int inc;
|
||||||
|
FILE *image;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
/* get it open */
|
||||||
|
image = fopen(file_name, "r");
|
||||||
|
if (image == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* read it in slowly */
|
||||||
|
count = 0;
|
||||||
|
while (1) {
|
||||||
|
inc = fread(buf, sizeof(buf), 1, image);
|
||||||
|
if (inc <= 0)
|
||||||
|
break;
|
||||||
|
if (me->parent->callback->dma_write_buffer(me->parent,
|
||||||
|
buf,
|
||||||
|
0 /*address-space*/,
|
||||||
|
addr+count,
|
||||||
|
inc /*nr-bytes*/,
|
||||||
|
1 /*violate ro*/) != inc) {
|
||||||
|
fclose(image);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
count += inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close down again */
|
||||||
|
fclose(image);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* inimplemented versions of each function */
|
/* inimplemented versions of each function */
|
||||||
|
|
||||||
@ -319,7 +360,7 @@ pass_device_interrupt(const device *me,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Simple console device: console@)x<address>,16
|
/* Simple console device: console@<address>,16
|
||||||
|
|
||||||
Input characters are taken from the keyboard, output characters
|
Input characters are taken from the keyboard, output characters
|
||||||
sent to the terminal. Echoing of characters is not disabled.
|
sent to the terminal. Echoing of characters is not disabled.
|
||||||
@ -423,7 +464,7 @@ console_io_read_buffer_callback(const device *me,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bzero(dest, nr_bytes);
|
memset(dest, 0, nr_bytes);
|
||||||
*(unsigned_1*)dest = val;
|
*(unsigned_1*)dest = val;
|
||||||
return nr_bytes;
|
return nr_bytes;
|
||||||
}
|
}
|
||||||
@ -438,7 +479,7 @@ console_io_write_buffer_callback(const device *me,
|
|||||||
unsigned_word cia)
|
unsigned_word cia)
|
||||||
{
|
{
|
||||||
console_device *console = (console_device*)me->data;
|
console_device *console = (console_device*)me->data;
|
||||||
unsigned_1 val = *(unsigned8*)source;
|
unsigned_1 val = *(unsigned_1*)source;
|
||||||
DTRACE_IO_WRITE_BUFFER(console);
|
DTRACE_IO_WRITE_BUFFER(console);
|
||||||
|
|
||||||
switch ((int)addr) {
|
switch ((int)addr) {
|
||||||
@ -529,7 +570,7 @@ icu_io_read_buffer_callback(const device *me,
|
|||||||
unsigned_1 val;
|
unsigned_1 val;
|
||||||
DTRACE_IO_READ_BUFFER(icu);
|
DTRACE_IO_READ_BUFFER(icu);
|
||||||
val = cpu_nr(processor);
|
val = cpu_nr(processor);
|
||||||
bzero(dest, nr_bytes);
|
memset(dest, 0, nr_bytes);
|
||||||
*(unsigned_1*)dest = val;
|
*(unsigned_1*)dest = val;
|
||||||
return nr_bytes;
|
return nr_bytes;
|
||||||
}
|
}
|
||||||
@ -605,7 +646,7 @@ halt_io_write_buffer_callback(const device *me,
|
|||||||
unsigned_word cia)
|
unsigned_word cia)
|
||||||
{
|
{
|
||||||
DTRACE_IO_WRITE_BUFFER(halt);
|
DTRACE_IO_WRITE_BUFFER(halt);
|
||||||
cpu_halt(processor, cia, was_exited, 0);
|
cpu_halt(processor, cia, was_exited, *(unsigned_1*)source);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -820,7 +861,7 @@ vm_io_read_buffer_callback(const device *me,
|
|||||||
{
|
{
|
||||||
DTRACE_IO_READ_BUFFER(vm);
|
DTRACE_IO_READ_BUFFER(vm);
|
||||||
if (add_vm_space(me, addr, nr_bytes, processor, cia) >= nr_bytes) {
|
if (add_vm_space(me, addr, nr_bytes, processor, cia) >= nr_bytes) {
|
||||||
bzero(dest, nr_bytes); /* always initialized to zero */
|
memset(dest, 0, nr_bytes); /* always initialized to zero */
|
||||||
return nr_bytes;
|
return nr_bytes;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1062,38 +1103,17 @@ file_init_callback(const device *me,
|
|||||||
psim *system)
|
psim *system)
|
||||||
{
|
{
|
||||||
unsigned_word addr;
|
unsigned_word addr;
|
||||||
unsigned count;
|
int count;
|
||||||
char *file_name;
|
char file_name[1024];
|
||||||
char buf;
|
|
||||||
FILE *image;
|
|
||||||
DTRACE_INIT(file);
|
DTRACE_INIT(file);
|
||||||
|
|
||||||
if ((file_name = strchr(me->name, ',')) == NULL
|
if (scand_uw_c(me->name, &addr, file_name, sizeof(file_name)) != 2)
|
||||||
|| scand_uw(me->name, &addr) != 1)
|
error("devices/file - Usage: file@<address>,<file-name>\n");
|
||||||
error("file_init_callback() invalid file device %s\n", me->name);
|
|
||||||
|
/* load the file */
|
||||||
/* open the file to load */
|
count = dma_file(me, file_name, addr);
|
||||||
file_name++; /* skip the `,' */
|
if (count < 0)
|
||||||
image = fopen(file_name, "r");
|
error("devices/%s - Problem loading file %s\n", me->name, file_name);
|
||||||
if (image == NULL)
|
|
||||||
error("file_init_callback() file open failed for %s\n", me->name);
|
|
||||||
|
|
||||||
/* read it in slowly */
|
|
||||||
count = 0;
|
|
||||||
while (fread(&buf, 1, 1, image) > 0) {
|
|
||||||
if (me->parent->callback->dma_write_buffer(me->parent,
|
|
||||||
&buf,
|
|
||||||
0 /*address-space*/,
|
|
||||||
addr+count,
|
|
||||||
1 /*nr-bytes*/,
|
|
||||||
1 /*violate ro*/) != 1)
|
|
||||||
error("file_init_callback() failed to write to address 0x%x, offset %d\n",
|
|
||||||
addr+count, count);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* close down again */
|
|
||||||
fclose(image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1114,8 +1134,9 @@ static device_callbacks const file_callbacks = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* HTAB: htab@0x<address>,<nr_bytes>
|
/* HTAB: htab@<address>,<nr_bytes>
|
||||||
PTE: pte@0x<effective-address>,0x<real-address>,<nr_bytes>
|
PTE: pte@<virtual-address>,<real-address>,<wimg>,<pp>,<nr_bytes>
|
||||||
|
PTE: pte@<virtual-address>,<real-address>,<wimg>,<pp>,<file>
|
||||||
|
|
||||||
HTAB defines the location (in physical memory) of a HASH table.
|
HTAB defines the location (in physical memory) of a HASH table.
|
||||||
PTE (as a child of HTAB) defines a mapping that is to be entered
|
PTE (as a child of HTAB) defines a mapping that is to be entered
|
||||||
@ -1131,22 +1152,115 @@ htab_init_callback(const device *me,
|
|||||||
psim *system)
|
psim *system)
|
||||||
{
|
{
|
||||||
DTRACE_INIT(htab);
|
DTRACE_INIT(htab);
|
||||||
|
if (WITH_TARGET_WORD_BITSIZE != 32)
|
||||||
|
error("devices/htab: only 32bit targets currently suported\n");
|
||||||
/* only the pte does work */
|
/* only the pte does work */
|
||||||
if (strncmp(me->name, "pte@", strlen("pte@")) == 0) {
|
if (strncmp(me->name, "pte@", strlen("pte@")) == 0) {
|
||||||
unsigned_word htab_ra;
|
unsigned32 htab_ra;
|
||||||
unsigned htab_nr_bytes;
|
unsigned htab_nr_bytes;
|
||||||
unsigned_word pte_ea;
|
signed32 pte_va; /* so that 0xff...0 is make 0xffffff00 */
|
||||||
unsigned_word pte_ra;
|
unsigned32 pte_ra;
|
||||||
unsigned pte_nr_bytes;
|
unsigned pte_nr_bytes;
|
||||||
|
unsigned pte_wimg;
|
||||||
|
unsigned pte_pp;
|
||||||
|
unsigned32 ra;
|
||||||
|
unsigned64 va;
|
||||||
|
unsigned32 htaborg;
|
||||||
|
unsigned32 htabmask;
|
||||||
|
unsigned32 n;
|
||||||
|
|
||||||
/* determine the location/size of the hash table */
|
/* determine the location/size of the hash table */
|
||||||
|
if (me->parent == NULL
|
||||||
|
|| strncmp(me->parent->name, "htab@", strlen("htab@")) != 0)
|
||||||
|
error("devices/%s - Parent is not a htab device\n", me->name);
|
||||||
if (scand_uw_u(me->parent->name, &htab_ra, &htab_nr_bytes) != 2)
|
if (scand_uw_u(me->parent->name, &htab_ra, &htab_nr_bytes) != 2)
|
||||||
error("htab_init_callback() htab entry %s invalid\n",
|
error("devices/%s - Usage: htab@<real-addr>,<nr_bytes>\n",
|
||||||
me->parent->name);
|
me->parent->name);
|
||||||
|
htabmask = EXTRACTED32(htab_nr_bytes - 1, 7, 15);
|
||||||
|
for (n = htab_nr_bytes; n > 1; n = n / 2) {
|
||||||
|
if (n % 2 != 0)
|
||||||
|
error("devices/%s - htabmask 0x%x (size 0x%x) not a power of two\n",
|
||||||
|
me->parent->name, htabmask, htab_nr_bytes);
|
||||||
|
}
|
||||||
|
htaborg = htab_ra;
|
||||||
|
if ((htaborg & INSERTED32(htabmask, 7, 15)) != 0) {
|
||||||
|
error("devices/%s - htaborg 0x%x not aligned to htabmask 0x%x\n",
|
||||||
|
me->parent->name, htaborg, htabmask);
|
||||||
|
}
|
||||||
|
|
||||||
/* determine the location/size of the mapping */
|
/* determine the location/size of the mapping */
|
||||||
if (scand_uw_uw_u(me->name, &pte_ea, &pte_ra, &pte_nr_bytes) != 3)
|
if (scand_uw_uw_u_u_u(me->name, &pte_va, &pte_ra,
|
||||||
error("htab_init_callback() pte entry %s invalid\n", me->name);
|
&pte_wimg, &pte_pp, &pte_nr_bytes) != 5) {
|
||||||
error("Map ea=0x%x, ra=0x%x, nr_bytes=%d using htab=0x%x, nr_bytes=%d\n",
|
int nr_bytes;
|
||||||
pte_ea, pte_ra, pte_nr_bytes, htab_ra, htab_nr_bytes);
|
char file_name[1024];
|
||||||
|
if (scand_uw_uw_u_u_c(me->name, &pte_va, &pte_ra, &pte_wimg, &pte_pp,
|
||||||
|
file_name, sizeof(file_name)) != 5)
|
||||||
|
error("devices/%s - Usage: %s\nor\t%s\n",
|
||||||
|
me->name,
|
||||||
|
"pte@<virtual-addr>,<real-addr>,<wimg>,<pp>,<nr-bytes>",
|
||||||
|
"pte@<virtual-addr>,<real-addr>,<wimg>,<pp>,<file>");
|
||||||
|
/* load/validate it */
|
||||||
|
nr_bytes = dma_file(me, file_name, pte_ra);
|
||||||
|
if (nr_bytes < 0)
|
||||||
|
error("devices/%s - problem loading file %s\n", me->name, file_name);
|
||||||
|
pte_nr_bytes = nr_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* go through all pages and create a pte for each */
|
||||||
|
for (ra = pte_ra, va = (signed32)pte_va;
|
||||||
|
ra < pte_ra + pte_nr_bytes;
|
||||||
|
ra += 1024, va += 1024) {
|
||||||
|
unsigned64 vpn = va << 12;
|
||||||
|
unsigned32 vsid = INSERTED32(EXTRACTED64(vpn, 0, 23), 0, 23);
|
||||||
|
unsigned32 page = INSERTED32(EXTRACTED64(vpn, 24, 39), 0, 15);
|
||||||
|
unsigned32 hash = INSERTED32(EXTRACTED32(vsid, 5, 23)
|
||||||
|
^ EXTRACTED32(page, 0, 15),
|
||||||
|
0, 18);
|
||||||
|
int h;
|
||||||
|
for (h = 0; h < 2; h++) {
|
||||||
|
unsigned32 pteg = (htaborg
|
||||||
|
| INSERTED32(EXTRACTED32(hash, 0, 8) & htabmask, 7, 15)
|
||||||
|
| INSERTED32(EXTRACTED32(hash, 9, 18), 16, 25));
|
||||||
|
int pti;
|
||||||
|
for (pti = 0; pti < 8; pti++, pteg += 8) {
|
||||||
|
unsigned32 pte0;
|
||||||
|
if (me->parent->callback->dma_read_buffer(me->parent,
|
||||||
|
&pte0,
|
||||||
|
0, /*space*/
|
||||||
|
pteg,
|
||||||
|
sizeof(pte0)) != 4)
|
||||||
|
error("htab_init_callback() failed to read a pte at 0x%x\n",
|
||||||
|
pteg);
|
||||||
|
if (!MASKED32(pte0, 0, 0)) {
|
||||||
|
/* empty pte fill it */
|
||||||
|
unsigned32 pte0 = (MASK32(0, 0)
|
||||||
|
| INSERTED32(EXTRACTED32(vsid, 0, 23), 1, 24)
|
||||||
|
| INSERTED32(h, 25, 25)
|
||||||
|
| INSERTED32(EXTRACTED32(page, 0, 5), 26, 31));
|
||||||
|
unsigned32 pte1 = (INSERTED32(EXTRACTED32(ra, 0, 19), 0, 19)
|
||||||
|
| INSERTED32(pte_wimg, 25, 28)
|
||||||
|
| INSERTED32(pte_pp, 30, 31));
|
||||||
|
if (me->parent->callback->dma_write_buffer(me->parent,
|
||||||
|
&pte0,
|
||||||
|
0, /*space*/
|
||||||
|
pteg,
|
||||||
|
sizeof(pte0),
|
||||||
|
1/*ro?*/) != 4
|
||||||
|
|| me->parent->callback->dma_write_buffer(me->parent,
|
||||||
|
&pte1,
|
||||||
|
0, /*space*/
|
||||||
|
pteg + 4,
|
||||||
|
sizeof(pte1),
|
||||||
|
1/*ro?*/) != 4)
|
||||||
|
error("htab_init_callback() failed to write a pte a 0x%x\n",
|
||||||
|
pteg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* re-hash */
|
||||||
|
hash = MASKED32(~hash, 0, 18);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1194,7 +1308,7 @@ static device_callbacks const sim_callbacks = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Load device: *binary@<file-name>
|
/* Load device: binary@<file-name>
|
||||||
|
|
||||||
Assuming that <file-name> is an executable file understood by BFD,
|
Assuming that <file-name> is an executable file understood by BFD,
|
||||||
this device loads or maps the relevant text/data segments into
|
this device loads or maps the relevant text/data segments into
|
||||||
@ -1281,20 +1395,19 @@ STATIC_INLINE_DEVICES void
|
|||||||
binary_init_callback(const device *me,
|
binary_init_callback(const device *me,
|
||||||
psim *system)
|
psim *system)
|
||||||
{
|
{
|
||||||
char file_name[100];
|
char file_name[1024];
|
||||||
bfd *image;
|
bfd *image;
|
||||||
DTRACE_INIT(binary);
|
DTRACE_INIT(binary);
|
||||||
|
|
||||||
/* get a file name */
|
/* get a file name */
|
||||||
if (scand_c(me->name, file_name, sizeof(file_name)) != 1)
|
if (scand_c(me->name, file_name, sizeof(file_name)) != 1)
|
||||||
error("load_binary_init_callback() invalid load-binary device %s\n",
|
error("devices/binary - Usage: binary@<file-name>\n");
|
||||||
me->name);
|
|
||||||
|
|
||||||
/* open the file */
|
/* open the file */
|
||||||
image = bfd_openr(file_name, NULL);
|
image = bfd_openr(file_name, NULL);
|
||||||
if (image == NULL) {
|
if (image == NULL) {
|
||||||
bfd_perror("open failed:");
|
bfd_perror("devices/binary");
|
||||||
error("nothing loaded\n");
|
error("devices/%s - the file %s not loaded\n", me->name, file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check it is valid */
|
/* check it is valid */
|
||||||
|
582
sim/ppc/igen.c
582
sim/ppc/igen.c
@ -513,16 +513,6 @@ struct _opcode_field {
|
|||||||
opcode_field *parent;
|
opcode_field *parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
static opcode_field *
|
|
||||||
opcode_field_new(void)
|
|
||||||
{
|
|
||||||
opcode_field *new_field = (opcode_field*)zalloc(sizeof(opcode_field));
|
|
||||||
ASSERT(new_field != NULL);
|
|
||||||
new_field->first = insn_size;
|
|
||||||
new_field->last = -1;
|
|
||||||
return new_field;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_opcode_field(opcode_field *field, int indent, int levels)
|
dump_opcode_field(opcode_field *field, int indent, int levels)
|
||||||
{
|
{
|
||||||
@ -575,7 +565,7 @@ typedef enum {
|
|||||||
insn_format,
|
insn_format,
|
||||||
insn_form,
|
insn_form,
|
||||||
insn_flags,
|
insn_flags,
|
||||||
insn_nmemonic,
|
insn_mnemonic,
|
||||||
insn_name,
|
insn_name,
|
||||||
insn_comment,
|
insn_comment,
|
||||||
nr_insn_table_fields
|
nr_insn_table_fields
|
||||||
@ -588,7 +578,8 @@ typedef enum {
|
|||||||
} function_table_fields;
|
} function_table_fields;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
model_name = insn_nmemonic,
|
model_default = insn_form,
|
||||||
|
model_name = insn_mnemonic,
|
||||||
model_identifer = insn_name,
|
model_identifer = insn_name,
|
||||||
model_func = insn_comment,
|
model_func = insn_comment,
|
||||||
} model_table_fields;
|
} model_table_fields;
|
||||||
@ -654,6 +645,12 @@ static insn *last_model_macro;
|
|||||||
static insn *model_functions;
|
static insn *model_functions;
|
||||||
static insn *last_model_function;
|
static insn *last_model_function;
|
||||||
|
|
||||||
|
static insn *model_internal;
|
||||||
|
static insn *last_model_internal;
|
||||||
|
|
||||||
|
static insn *model_data;
|
||||||
|
static insn *last_model_data;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
insn_table_insert_function(insn_table *table,
|
insn_table_insert_function(insn_table *table,
|
||||||
table_entry *file_entry)
|
table_entry *file_entry)
|
||||||
@ -670,159 +667,6 @@ insn_table_insert_function(insn_table *table,
|
|||||||
table->last_function = new_function;
|
table->last_function = new_function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
model_table_insert(insn_table *table,
|
|
||||||
table_entry *file_entry)
|
|
||||||
{
|
|
||||||
/* create a new model */
|
|
||||||
model *new_model = ZALLOC(model);
|
|
||||||
model_func_unit *func_unit;
|
|
||||||
char *ptr, *end, *end_name, *comment, *name;
|
|
||||||
int ch;
|
|
||||||
int name_len;
|
|
||||||
int func_name_len;
|
|
||||||
unsigned unit, mask;
|
|
||||||
int number;
|
|
||||||
|
|
||||||
new_model->name = file_entry->fields[model_identifer];
|
|
||||||
new_model->printable_name = file_entry->fields[model_name];
|
|
||||||
name_len = strlen(new_model->name);
|
|
||||||
|
|
||||||
/* append it to the end of the model list */
|
|
||||||
if (last_model)
|
|
||||||
last_model->next = new_model;
|
|
||||||
else
|
|
||||||
models = new_model;
|
|
||||||
last_model = new_model;
|
|
||||||
|
|
||||||
/* Parse the function units separated by commas */
|
|
||||||
unit = 1;
|
|
||||||
for (ptr = file_entry->fields[model_func];
|
|
||||||
((ch = *ptr) != '\0') && (ch != '\n');
|
|
||||||
ptr = (*end == ',') ? end+1 : end) {
|
|
||||||
|
|
||||||
while (ch == ' ' || ch == '\t')
|
|
||||||
ch = *++ptr;
|
|
||||||
|
|
||||||
if (!ch || ch == '\n')
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Search for comma or newline ending field */
|
|
||||||
end = ptr;
|
|
||||||
end_name = (char *)0;
|
|
||||||
|
|
||||||
if (ch == ',')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
while (ch != '\0' && ch != ',' && ch != '\n') {
|
|
||||||
if (end_name == (char *)0 && (ch == '=' || isspace(ch)))
|
|
||||||
end_name = end;
|
|
||||||
|
|
||||||
ch = *++end;
|
|
||||||
}
|
|
||||||
if (!end_name)
|
|
||||||
end_name = end;
|
|
||||||
|
|
||||||
func_unit = ZALLOC(model_func_unit);
|
|
||||||
if (new_model->func_unit_end)
|
|
||||||
new_model->func_unit_end->next = func_unit;
|
|
||||||
else
|
|
||||||
new_model->func_unit_start = func_unit;
|
|
||||||
|
|
||||||
new_model->func_unit_end = func_unit;
|
|
||||||
|
|
||||||
/* Record function unit name as model name _ unit name */
|
|
||||||
func_name_len = name_len + end_name - ptr + 2;
|
|
||||||
if (table->max_func_unit_name_len < func_name_len)
|
|
||||||
table->max_func_unit_name_len = func_name_len;
|
|
||||||
|
|
||||||
func_unit->name = name = (char *)zalloc(func_name_len);
|
|
||||||
memcpy(name, new_model->name, name_len);
|
|
||||||
name[name_len] = '_';
|
|
||||||
memcpy(name + name_len + 1, ptr, end_name - ptr);
|
|
||||||
|
|
||||||
/* See if there are multiple functional units */
|
|
||||||
if (*end_name == '=') {
|
|
||||||
number = 0;
|
|
||||||
for(end_name++; end_name < end && isdigit(*end_name); end_name++)
|
|
||||||
number = number * 10 + (*end_name - '0');
|
|
||||||
} else {
|
|
||||||
number = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now figure out the mask for these unit(s) */
|
|
||||||
func_unit->number = number;
|
|
||||||
mask = 0;
|
|
||||||
while (number--) {
|
|
||||||
ASSERT(unit != 0);
|
|
||||||
mask |= unit;
|
|
||||||
unit <<= 1;
|
|
||||||
}
|
|
||||||
func_unit->mask = mask;
|
|
||||||
table->max_func_unit_mask |= mask;
|
|
||||||
|
|
||||||
/* Now figure out comments */
|
|
||||||
for (comment = end_name; comment < end && ((ch = *comment) == ' ' || ch == '\t'); comment++)
|
|
||||||
;
|
|
||||||
|
|
||||||
if (comment < end) {
|
|
||||||
func_unit->comment = (char *)zalloc(end - comment + 1);
|
|
||||||
memcpy(func_unit->comment, comment, end - comment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add an 'sentinel' function unit at the end to simpify the loop */
|
|
||||||
func_unit = ZALLOC(model_func_unit);
|
|
||||||
if (new_model->func_unit_end)
|
|
||||||
new_model->func_unit_end->next = func_unit;
|
|
||||||
else
|
|
||||||
new_model->func_unit_start = func_unit;
|
|
||||||
|
|
||||||
new_model->func_unit_end = func_unit;
|
|
||||||
|
|
||||||
/* Record function unit name as model name _ unit name */
|
|
||||||
func_name_len = name_len + sizeof("_SENTINEL");
|
|
||||||
if (table->max_func_unit_name_len < func_name_len)
|
|
||||||
table->max_func_unit_name_len = func_name_len;
|
|
||||||
|
|
||||||
func_unit->name = name = (char *)zalloc(func_name_len);
|
|
||||||
func_unit->number = 0;
|
|
||||||
func_unit->mask = unit;
|
|
||||||
func_unit->comment = "dummy";
|
|
||||||
table->max_func_unit_mask |= unit;
|
|
||||||
|
|
||||||
memcpy(name, new_model->name, name_len);
|
|
||||||
strcpy(name + name_len, "_SENTINEL");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
model_table_insert_macro(insn_table *table,
|
|
||||||
table_entry *file_entry)
|
|
||||||
{
|
|
||||||
insn *macro = ZALLOC(insn);
|
|
||||||
macro->file_entry = file_entry;
|
|
||||||
if (last_model_macro)
|
|
||||||
last_model_macro->next = macro;
|
|
||||||
else
|
|
||||||
model_macros = macro;
|
|
||||||
last_model_macro = macro;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
model_table_insert_function(insn_table *table,
|
|
||||||
table_entry *file_entry)
|
|
||||||
{
|
|
||||||
insn *func = ZALLOC(insn);
|
|
||||||
func->file_entry = file_entry;
|
|
||||||
if (last_model_function)
|
|
||||||
last_model_function->next = func;
|
|
||||||
else
|
|
||||||
model_functions = func;
|
|
||||||
last_model_function = func;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
insn_table_insert_insn(insn_table *table,
|
insn_table_insert_insn(insn_table *table,
|
||||||
table_entry *file_entry,
|
table_entry *file_entry,
|
||||||
@ -877,11 +721,12 @@ insn_table_find_opcode_field(insn *insns,
|
|||||||
opcode_rules *rule,
|
opcode_rules *rule,
|
||||||
int string_only)
|
int string_only)
|
||||||
{
|
{
|
||||||
opcode_field *curr_opcode = opcode_field_new();
|
opcode_field *curr_opcode = ZALLOC(opcode_field);
|
||||||
insn *entry;
|
insn *entry;
|
||||||
|
|
||||||
ASSERT(rule);
|
ASSERT(rule);
|
||||||
|
|
||||||
|
curr_opcode->first = insn_size;
|
||||||
|
curr_opcode->last = -1;
|
||||||
for (entry = insns; entry != NULL; entry = entry->next) {
|
for (entry = insns; entry != NULL; entry = entry->next) {
|
||||||
insn_fields *fields = entry->fields;
|
insn_fields *fields = entry->fields;
|
||||||
opcode_field new_opcode;
|
opcode_field new_opcode;
|
||||||
@ -1121,6 +966,147 @@ insn_table_expand_insns(insn_table *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
model_table_insert(insn_table *table,
|
||||||
|
table_entry *file_entry)
|
||||||
|
{
|
||||||
|
/* create a new model */
|
||||||
|
model *new_model = ZALLOC(model);
|
||||||
|
model_func_unit *func_unit;
|
||||||
|
char *ptr, *end, *end_name, *comment, *name;
|
||||||
|
int ch;
|
||||||
|
int name_len;
|
||||||
|
int func_name_len;
|
||||||
|
unsigned unit, mask;
|
||||||
|
int number;
|
||||||
|
|
||||||
|
new_model->name = file_entry->fields[model_identifer];
|
||||||
|
new_model->printable_name = file_entry->fields[model_name];
|
||||||
|
name_len = strlen(new_model->name);
|
||||||
|
|
||||||
|
/* append it to the end of the model list */
|
||||||
|
if (last_model)
|
||||||
|
last_model->next = new_model;
|
||||||
|
else
|
||||||
|
models = new_model;
|
||||||
|
last_model = new_model;
|
||||||
|
|
||||||
|
/* Parse the function units separated by commas */
|
||||||
|
unit = 1;
|
||||||
|
for (ptr = file_entry->fields[model_func];
|
||||||
|
((ch = *ptr) != '\0') && (ch != '\n');
|
||||||
|
ptr = (*end == ',') ? end+1 : end) {
|
||||||
|
|
||||||
|
while (ch == ' ' || ch == '\t')
|
||||||
|
ch = *++ptr;
|
||||||
|
|
||||||
|
if (!ch || ch == '\n')
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Search for comma or newline ending field */
|
||||||
|
end = ptr;
|
||||||
|
end_name = (char *)0;
|
||||||
|
|
||||||
|
if (ch == ',')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
while (ch != '\0' && ch != ',' && ch != '\n') {
|
||||||
|
if (end_name == (char *)0 && (ch == '=' || isspace(ch)))
|
||||||
|
end_name = end;
|
||||||
|
|
||||||
|
ch = *++end;
|
||||||
|
}
|
||||||
|
if (!end_name)
|
||||||
|
end_name = end;
|
||||||
|
|
||||||
|
func_unit = ZALLOC(model_func_unit);
|
||||||
|
if (new_model->func_unit_end)
|
||||||
|
new_model->func_unit_end->next = func_unit;
|
||||||
|
else
|
||||||
|
new_model->func_unit_start = func_unit;
|
||||||
|
|
||||||
|
new_model->func_unit_end = func_unit;
|
||||||
|
|
||||||
|
/* Record function unit name as model name _ unit name */
|
||||||
|
func_name_len = name_len + end_name - ptr + 2;
|
||||||
|
if (table->max_func_unit_name_len < func_name_len)
|
||||||
|
table->max_func_unit_name_len = func_name_len;
|
||||||
|
|
||||||
|
func_unit->name = name = (char *)zalloc(func_name_len);
|
||||||
|
memcpy(name, new_model->name, name_len);
|
||||||
|
name[name_len] = '_';
|
||||||
|
memcpy(name + name_len + 1, ptr, end_name - ptr);
|
||||||
|
|
||||||
|
/* See if there are multiple functional units */
|
||||||
|
if (*end_name == '=') {
|
||||||
|
number = 0;
|
||||||
|
for(end_name++; end_name < end && isdigit(*end_name); end_name++)
|
||||||
|
number = number * 10 + (*end_name - '0');
|
||||||
|
} else {
|
||||||
|
number = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now figure out the mask for these unit(s) */
|
||||||
|
func_unit->number = number;
|
||||||
|
mask = 0;
|
||||||
|
while (number--) {
|
||||||
|
ASSERT(unit != 0);
|
||||||
|
mask |= unit;
|
||||||
|
unit <<= 1;
|
||||||
|
}
|
||||||
|
func_unit->mask = mask;
|
||||||
|
table->max_func_unit_mask |= mask;
|
||||||
|
|
||||||
|
/* Now figure out comments */
|
||||||
|
for (comment = end_name; comment < end && ((ch = *comment) == ' ' || ch == '\t'); comment++)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (comment < end) {
|
||||||
|
func_unit->comment = (char *)zalloc(end - comment + 1);
|
||||||
|
memcpy(func_unit->comment, comment, end - comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add an 'sentinel' function unit at the end to simpify the loop */
|
||||||
|
func_unit = ZALLOC(model_func_unit);
|
||||||
|
if (new_model->func_unit_end)
|
||||||
|
new_model->func_unit_end->next = func_unit;
|
||||||
|
else
|
||||||
|
new_model->func_unit_start = func_unit;
|
||||||
|
|
||||||
|
new_model->func_unit_end = func_unit;
|
||||||
|
|
||||||
|
/* Record function unit name as model name _ unit name */
|
||||||
|
func_name_len = name_len + sizeof("_SENTINEL");
|
||||||
|
if (table->max_func_unit_name_len < func_name_len)
|
||||||
|
table->max_func_unit_name_len = func_name_len;
|
||||||
|
|
||||||
|
func_unit->name = name = (char *)zalloc(func_name_len);
|
||||||
|
func_unit->number = 0;
|
||||||
|
func_unit->mask = unit;
|
||||||
|
func_unit->comment = "dummy";
|
||||||
|
table->max_func_unit_mask |= unit;
|
||||||
|
|
||||||
|
memcpy(name, new_model->name, name_len);
|
||||||
|
strcpy(name + name_len, "_SENTINEL");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
model_table_insert_specific(insn_table *table,
|
||||||
|
table_entry *file_entry,
|
||||||
|
insn **start_ptr,
|
||||||
|
insn **end_ptr)
|
||||||
|
{
|
||||||
|
insn *ptr = ZALLOC(insn);
|
||||||
|
ptr->file_entry = file_entry;
|
||||||
|
if (*end_ptr)
|
||||||
|
(*end_ptr)->next = ptr;
|
||||||
|
else
|
||||||
|
(*start_ptr) = ptr;
|
||||||
|
(*end_ptr) = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static insn_table *
|
static insn_table *
|
||||||
insn_table_load_insns(char *file_name)
|
insn_table_load_insns(char *file_name)
|
||||||
@ -1139,10 +1125,16 @@ insn_table_load_insns(char *file_name)
|
|||||||
model_table_insert(table, file_entry);
|
model_table_insert(table, file_entry);
|
||||||
}
|
}
|
||||||
else if (it_is("model-macro", file_entry->fields[insn_flags])) {
|
else if (it_is("model-macro", file_entry->fields[insn_flags])) {
|
||||||
model_table_insert_macro(table, file_entry);
|
model_table_insert_specific(table, file_entry, &model_macros, &last_model_macro);
|
||||||
}
|
}
|
||||||
else if (it_is("model-function", file_entry->fields[insn_flags])) {
|
else if (it_is("model-function", file_entry->fields[insn_flags])) {
|
||||||
model_table_insert_function(table, file_entry);
|
model_table_insert_specific(table, file_entry, &model_functions, &last_model_function);
|
||||||
|
}
|
||||||
|
else if (it_is("model-internal", file_entry->fields[insn_flags])) {
|
||||||
|
model_table_insert_specific(table, file_entry, &model_internal, &last_model_internal);
|
||||||
|
}
|
||||||
|
else if (it_is("model-data", file_entry->fields[insn_flags])) {
|
||||||
|
model_table_insert_specific(table, file_entry, &model_data, &last_model_data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
insn_fields *fields;
|
insn_fields *fields;
|
||||||
@ -1367,6 +1359,7 @@ lf_print_idecode_table(lf *file,
|
|||||||
lf_printf(file, "while (1) {\n");
|
lf_printf(file, "while (1) {\n");
|
||||||
lf_indent(file, +2);
|
lf_indent(file, +2);
|
||||||
{
|
{
|
||||||
|
lf_printf(file, "/* nonzero mask -> another table */\n");
|
||||||
lf_printf(file, "while (table_entry->mask != 0) {\n");
|
lf_printf(file, "while (table_entry->mask != 0) {\n");
|
||||||
lf_indent(file, +2);
|
lf_indent(file, +2);
|
||||||
{
|
{
|
||||||
@ -1378,24 +1371,26 @@ lf_print_idecode_table(lf *file,
|
|||||||
}
|
}
|
||||||
lf_indent(file, -2);
|
lf_indent(file, -2);
|
||||||
lf_printf(file, "}\n");
|
lf_printf(file, "}\n");
|
||||||
if (!idecode_cache && can_assume_leaf) {
|
lf_printf(file, "ASSERT(table_entry->mask == 0);\n");
|
||||||
|
if (can_assume_leaf)
|
||||||
|
lf_printf(file, "ASSERT(table_entry->shift == 0);\n");
|
||||||
|
else {
|
||||||
|
lf_printf(file, "if (table_entry->shift == 0)\n");
|
||||||
|
lf_indent(file, +2);
|
||||||
|
}
|
||||||
|
if (idecode_cache) {
|
||||||
|
lf_printf(file, "return (((idecode_crack*)\n");
|
||||||
|
lf_printf(file, " table_entry->function_or_table)\n");
|
||||||
|
lf_printf(file, " (%s));\n", cache_idecode_actual);
|
||||||
|
}
|
||||||
|
else {
|
||||||
lf_printf(file, "return (((idecode_semantic*)\n");
|
lf_printf(file, "return (((idecode_semantic*)\n");
|
||||||
lf_printf(file, " table_entry->function_or_table)\n");
|
lf_printf(file, " table_entry->function_or_table)\n");
|
||||||
lf_printf(file, " (%s));\n", semantic_actual);
|
lf_printf(file, " (%s));\n", semantic_actual);
|
||||||
}
|
}
|
||||||
else if (!idecode_cache && !can_assume_leaf) {
|
|
||||||
lf_printf(file, "if (table_entry->shift == 0)");
|
|
||||||
lf_printf(file, " return (((idecode_semantic*)\n");
|
|
||||||
lf_printf(file, " table_entry->function_or_table)\n");
|
|
||||||
lf_printf(file, " (%s));\n", semantic_actual);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lf_printf(file, "if (table_entry->shift == 0)\n");
|
|
||||||
lf_printf(file, " return (((idecode_crack*)\n");
|
|
||||||
lf_printf(file, " table_entry->function_or_table)\n");
|
|
||||||
lf_printf(file, " (%s));\n", cache_idecode_actual);
|
|
||||||
}
|
|
||||||
if (!can_assume_leaf) {
|
if (!can_assume_leaf) {
|
||||||
|
lf_indent(file, -2);
|
||||||
|
lf_printf(file, "/* must be a boolean */\n");
|
||||||
lf_printf(file, "opcode = (instruction & table_entry->shift) != 0;\n");
|
lf_printf(file, "opcode = (instruction & table_entry->shift) != 0;\n");
|
||||||
lf_printf(file, "table = ((idecode_table_entry*)\n");
|
lf_printf(file, "table = ((idecode_table_entry*)\n");
|
||||||
lf_printf(file, " table_entry->function_or_table);\n");
|
lf_printf(file, " table_entry->function_or_table);\n");
|
||||||
@ -1616,9 +1611,11 @@ dump_traverse(insn_table *table)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
semantics_h_print_function(lf *file,
|
lf_print_semantic_function_header(lf *file,
|
||||||
char *basename,
|
char *basename,
|
||||||
insn_bits *expanded_bits)
|
insn_bits *expanded_bits,
|
||||||
|
int is_function_definition,
|
||||||
|
int is_inline_function)
|
||||||
{
|
{
|
||||||
lf_printf(file, "\n");
|
lf_printf(file, "\n");
|
||||||
lf_printf(file, "STATIC_SEMANTICS unsigned_word ");
|
lf_printf(file, "STATIC_SEMANTICS unsigned_word ");
|
||||||
@ -1626,8 +1623,11 @@ semantics_h_print_function(lf *file,
|
|||||||
basename,
|
basename,
|
||||||
expanded_bits,
|
expanded_bits,
|
||||||
function_name_prefix_semantics);
|
function_name_prefix_semantics);
|
||||||
lf_printf(file, "\n(%s);\n",
|
lf_printf(file, "\n(%s)",
|
||||||
(idecode_cache ? cache_semantic_formal : semantic_formal));
|
(idecode_cache ? cache_semantic_formal : semantic_formal));
|
||||||
|
if (!is_function_definition)
|
||||||
|
lf_printf(file, ";");
|
||||||
|
lf_printf(file, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1638,9 +1638,11 @@ semantics_h_leaf(insn_table *entry,
|
|||||||
{
|
{
|
||||||
lf *file = (lf*)data;
|
lf *file = (lf*)data;
|
||||||
ASSERT(entry->nr_insn == 1);
|
ASSERT(entry->nr_insn == 1);
|
||||||
semantics_h_print_function(file,
|
lf_print_semantic_function_header(file,
|
||||||
entry->insns->file_entry->fields[insn_name],
|
entry->insns->file_entry->fields[insn_name],
|
||||||
entry->expanded_bits);
|
entry->expanded_bits,
|
||||||
|
0/* isnt function definition*/,
|
||||||
|
!idecode_cache && entry->parent->opcode_rule->use_switch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1649,9 +1651,11 @@ semantics_h_insn(insn_table *entry,
|
|||||||
insn *instruction)
|
insn *instruction)
|
||||||
{
|
{
|
||||||
lf *file = (lf*)data;
|
lf *file = (lf*)data;
|
||||||
semantics_h_print_function(file,
|
lf_print_semantic_function_header(file,
|
||||||
instruction->file_entry->fields[insn_name],
|
instruction->file_entry->fields[insn_name],
|
||||||
NULL);
|
NULL,
|
||||||
|
0/*isnt function definition*/,
|
||||||
|
0/*isnt inline function*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1662,9 +1666,11 @@ semantics_h_function(insn_table *entry,
|
|||||||
lf *file = (lf*)data;
|
lf *file = (lf*)data;
|
||||||
if (function->fields[function_type] == NULL
|
if (function->fields[function_type] == NULL
|
||||||
|| function->fields[function_type][0] == '\0') {
|
|| function->fields[function_type][0] == '\0') {
|
||||||
semantics_h_print_function(file,
|
lf_print_semantic_function_header(file,
|
||||||
function->fields[function_name],
|
function->fields[function_name],
|
||||||
NULL);
|
NULL,
|
||||||
|
0/*isnt function definition*/,
|
||||||
|
1/*is inline function*/);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lf_printf(file, "\n");
|
lf_printf(file, "\n");
|
||||||
@ -2280,13 +2286,16 @@ static void
|
|||||||
lf_print_c_semantic_function(lf *file,
|
lf_print_c_semantic_function(lf *file,
|
||||||
insn *instruction,
|
insn *instruction,
|
||||||
insn_bits *expanded_bits,
|
insn_bits *expanded_bits,
|
||||||
opcode_field *opcodes)
|
opcode_field *opcodes,
|
||||||
|
int is_inline_function)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* build the semantic routine to execute the instruction */
|
/* build the semantic routine to execute the instruction */
|
||||||
lf_print_c_semantic_function_header(file,
|
lf_print_semantic_function_header(file,
|
||||||
instruction->file_entry->fields[insn_name],
|
instruction->file_entry->fields[insn_name],
|
||||||
expanded_bits);
|
expanded_bits,
|
||||||
|
1/*is-function-definition*/,
|
||||||
|
is_inline_function);
|
||||||
lf_print_c_semantic(file,
|
lf_print_c_semantic(file,
|
||||||
instruction,
|
instruction,
|
||||||
expanded_bits,
|
expanded_bits,
|
||||||
@ -2307,7 +2316,8 @@ semantics_c_leaf(insn_table *entry,
|
|||||||
lf_print_c_semantic_function(file,
|
lf_print_c_semantic_function(file,
|
||||||
entry->insns,
|
entry->insns,
|
||||||
entry->expanded_bits,
|
entry->expanded_bits,
|
||||||
entry->parent->opcode);
|
entry->parent->opcode,
|
||||||
|
!idecode_cache && entry->parent->opcode_rule->use_switch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2317,7 +2327,8 @@ semantics_c_insn(insn_table *table,
|
|||||||
{
|
{
|
||||||
lf *file = (lf*)data;
|
lf *file = (lf*)data;
|
||||||
lf_print_c_semantic_function(file, instruction,
|
lf_print_c_semantic_function(file, instruction,
|
||||||
NULL, NULL);
|
NULL, NULL,
|
||||||
|
0/*isnt_inline_function*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2328,9 +2339,11 @@ semantics_c_function(insn_table *table,
|
|||||||
lf *file = (lf*)data;
|
lf *file = (lf*)data;
|
||||||
if (function->fields[function_type] == NULL
|
if (function->fields[function_type] == NULL
|
||||||
|| function->fields[function_type][0] == '\0') {
|
|| function->fields[function_type][0] == '\0') {
|
||||||
lf_print_c_semantic_function_header(file,
|
lf_print_semantic_function_header(file,
|
||||||
function->fields[function_name],
|
function->fields[function_name],
|
||||||
NULL);
|
NULL,
|
||||||
|
1/*is function definition*/,
|
||||||
|
1/*is inline function*/);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lf_printf(file, "\n");
|
lf_printf(file, "\n");
|
||||||
@ -2468,7 +2481,7 @@ idecode_table_leaf(insn_table *entry,
|
|||||||
}
|
}
|
||||||
else if (entry->opcode_rule->use_switch) {
|
else if (entry->opcode_rule->use_switch) {
|
||||||
/* table calling switch statement */
|
/* table calling switch statement */
|
||||||
lf_printf(file, " /*%d*/ { -1, 0, ",
|
lf_printf(file, " /*%d*/ { 0, 0, ",
|
||||||
entry->opcode_nr);
|
entry->opcode_nr);
|
||||||
lf_print_table_name(file, entry);
|
lf_print_table_name(file, entry);
|
||||||
lf_printf(file, " },\n");
|
lf_printf(file, " },\n");
|
||||||
@ -2552,8 +2565,13 @@ idecode_switch_leaf(insn_table *entry,
|
|||||||
ASSERT(entry->parent != NULL);
|
ASSERT(entry->parent != NULL);
|
||||||
ASSERT(depth == 0);
|
ASSERT(depth == 0);
|
||||||
ASSERT(entry->parent->opcode_rule->use_switch);
|
ASSERT(entry->parent->opcode_rule->use_switch);
|
||||||
|
ASSERT(entry->parent->opcode);
|
||||||
|
|
||||||
lf_printf(file, "case %d:\n", entry->opcode_nr);
|
if (!entry->parent->opcode->is_boolean
|
||||||
|
|| entry->opcode_nr == 0)
|
||||||
|
lf_printf(file, "case %d:\n", entry->opcode_nr);
|
||||||
|
else
|
||||||
|
lf_printf(file, "default:\n");
|
||||||
lf_indent(file, +2);
|
lf_indent(file, +2);
|
||||||
{
|
{
|
||||||
if (entry->opcode == NULL) {
|
if (entry->opcode == NULL) {
|
||||||
@ -2575,8 +2593,7 @@ idecode_switch_leaf(insn_table *entry,
|
|||||||
lf_print_idecode_switch(file, entry);
|
lf_print_idecode_switch(file, entry);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* switch calling table */
|
/* switch looking up a table */
|
||||||
lf_printf(file, "return ");
|
|
||||||
lf_print_idecode_table(file, entry);
|
lf_print_idecode_table(file, entry);
|
||||||
}
|
}
|
||||||
lf_printf(file, "break;\n");
|
lf_printf(file, "break;\n");
|
||||||
@ -2602,8 +2619,10 @@ idecode_switch_end(insn_table *table,
|
|||||||
lf *file = (lf*)data;
|
lf *file = (lf*)data;
|
||||||
ASSERT(depth == 0);
|
ASSERT(depth == 0);
|
||||||
ASSERT(table->opcode_rule->use_switch);
|
ASSERT(table->opcode_rule->use_switch);
|
||||||
|
ASSERT(table->opcode);
|
||||||
|
|
||||||
if (table->opcode_rule->use_switch == 1) {
|
if (table->opcode_rule->use_switch == 1
|
||||||
|
&& !table->opcode->is_boolean) {
|
||||||
lf_printf(file, "default:\n");
|
lf_printf(file, "default:\n");
|
||||||
lf_print_idecode_switch_illegal(file);
|
lf_print_idecode_switch_illegal(file);
|
||||||
}
|
}
|
||||||
@ -2642,6 +2661,47 @@ lf_print_idecode_switch(lf *file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
lf_print_idecode_switch_function_header(lf *file,
|
||||||
|
insn_table *table,
|
||||||
|
int is_function_definition)
|
||||||
|
{
|
||||||
|
lf_printf(file, "\n");
|
||||||
|
lf_printf(file, "static ");
|
||||||
|
if (idecode_cache)
|
||||||
|
lf_printf(file, "idecode_semantic *");
|
||||||
|
else
|
||||||
|
lf_printf(file, "unsigned_word");
|
||||||
|
if (is_function_definition)
|
||||||
|
lf_printf(file, "\n");
|
||||||
|
else
|
||||||
|
lf_printf(file, " ");
|
||||||
|
lf_print_table_name(file, table);
|
||||||
|
lf_printf(file, "\n(%s)",
|
||||||
|
(idecode_cache ? cache_idecode_formal : semantic_formal));
|
||||||
|
if (!is_function_definition)
|
||||||
|
lf_printf(file, ";");
|
||||||
|
lf_printf(file, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
idecode_declare_if_switch(insn_table *table,
|
||||||
|
void *data,
|
||||||
|
int depth)
|
||||||
|
{
|
||||||
|
lf *file = (lf*)data;
|
||||||
|
|
||||||
|
if (table->opcode_rule->use_switch
|
||||||
|
&& table->parent != NULL /* don't declare the top one yet */
|
||||||
|
&& !table->parent->opcode_rule->use_switch) {
|
||||||
|
lf_print_idecode_switch_function_header(file,
|
||||||
|
table,
|
||||||
|
0/*isnt function definition*/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
idecode_expand_if_switch(insn_table *table,
|
idecode_expand_if_switch(insn_table *table,
|
||||||
void *data,
|
void *data,
|
||||||
@ -2652,11 +2712,9 @@ idecode_expand_if_switch(insn_table *table,
|
|||||||
if (table->opcode_rule->use_switch
|
if (table->opcode_rule->use_switch
|
||||||
&& table->parent != NULL /* don't expand the top one yet */
|
&& table->parent != NULL /* don't expand the top one yet */
|
||||||
&& !table->parent->opcode_rule->use_switch) {
|
&& !table->parent->opcode_rule->use_switch) {
|
||||||
lf_printf(file, "\n");
|
lf_print_idecode_switch_function_header(file,
|
||||||
lf_printf(file, "STATIC_INLINE_IDECODE void\n");
|
table,
|
||||||
lf_print_table_name(file, table);
|
1/*is function definition*/);
|
||||||
lf_printf(file, "\n(%s)\n",
|
|
||||||
(idecode_cache ? cache_idecode_formal : semantic_formal));
|
|
||||||
lf_printf(file, "{\n");
|
lf_printf(file, "{\n");
|
||||||
{
|
{
|
||||||
lf_indent(file, +2);
|
lf_indent(file, +2);
|
||||||
@ -2672,7 +2730,8 @@ static void
|
|||||||
lf_print_c_cracker_function(lf *file,
|
lf_print_c_cracker_function(lf *file,
|
||||||
insn *instruction,
|
insn *instruction,
|
||||||
insn_bits *expanded_bits,
|
insn_bits *expanded_bits,
|
||||||
opcode_field *opcodes)
|
opcode_field *opcodes,
|
||||||
|
int is_inline_function)
|
||||||
{
|
{
|
||||||
/* if needed, generate code to enter this routine into a cache */
|
/* if needed, generate code to enter this routine into a cache */
|
||||||
lf_printf(file, "\n");
|
lf_printf(file, "\n");
|
||||||
@ -2698,11 +2757,13 @@ idecode_crack_leaf(insn_table *entry,
|
|||||||
ASSERT(entry->nr_insn == 1
|
ASSERT(entry->nr_insn == 1
|
||||||
&& entry->opcode == NULL
|
&& entry->opcode == NULL
|
||||||
&& entry->parent != NULL
|
&& entry->parent != NULL
|
||||||
&& entry->parent->opcode != NULL);
|
&& entry->parent->opcode != NULL
|
||||||
|
&& entry->parent->opcode_rule != NULL);
|
||||||
lf_print_c_cracker_function(file,
|
lf_print_c_cracker_function(file,
|
||||||
entry->insns,
|
entry->insns,
|
||||||
entry->expanded_bits,
|
entry->expanded_bits,
|
||||||
entry->opcode);
|
entry->opcode,
|
||||||
|
entry->parent->opcode_rule->use_switch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2714,7 +2775,8 @@ idecode_crack_insn(insn_table *entry,
|
|||||||
lf_print_c_cracker_function(file,
|
lf_print_c_cracker_function(file,
|
||||||
instruction,
|
instruction,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL,
|
||||||
|
0/*isnt inline function*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2812,6 +2874,12 @@ gen_idecode_c(insn_table *table, lf *file)
|
|||||||
idecode_crack_insn);
|
idecode_crack_insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* output switch function declarations where needed by tables */
|
||||||
|
insn_table_traverse_tree(table,
|
||||||
|
file,
|
||||||
|
1,
|
||||||
|
idecode_declare_if_switch, /* START */
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
/* output tables where needed */
|
/* output tables where needed */
|
||||||
for (depth = insn_table_depth(table);
|
for (depth = insn_table_depth(table);
|
||||||
@ -2850,7 +2918,7 @@ gen_idecode_c(insn_table *table, lf *file)
|
|||||||
lf_indent(file, -2);
|
lf_indent(file, -2);
|
||||||
lf_printf(file, "}\n");
|
lf_printf(file, "}\n");
|
||||||
lf_printf(file, "\n");
|
lf_printf(file, "\n");
|
||||||
lf_printf(file, "#endif\n");
|
lf_printf(file, "#endif /* _IDECODE_C_ */\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2901,7 +2969,7 @@ gen_itable_h(insn_table *table, lf *file)
|
|||||||
lf_printf(file, " char *format;\n");
|
lf_printf(file, " char *format;\n");
|
||||||
lf_printf(file, " char *form;\n");
|
lf_printf(file, " char *form;\n");
|
||||||
lf_printf(file, " char *flags;\n");
|
lf_printf(file, " char *flags;\n");
|
||||||
lf_printf(file, " char *nmemonic;\n");
|
lf_printf(file, " char *mnemonic;\n");
|
||||||
lf_printf(file, " char *name;\n");
|
lf_printf(file, " char *name;\n");
|
||||||
lf_printf(file, "} itable_info;\n");
|
lf_printf(file, "} itable_info;\n");
|
||||||
lf_printf(file, "\n");
|
lf_printf(file, "\n");
|
||||||
@ -2930,7 +2998,7 @@ itable_c_insn(insn_table *entry,
|
|||||||
lf_printf(file, " \"%s\",\n", fields[insn_format]);
|
lf_printf(file, " \"%s\",\n", fields[insn_format]);
|
||||||
lf_printf(file, " \"%s\",\n", fields[insn_form]);
|
lf_printf(file, " \"%s\",\n", fields[insn_form]);
|
||||||
lf_printf(file, " \"%s\",\n", fields[insn_flags]);
|
lf_printf(file, " \"%s\",\n", fields[insn_flags]);
|
||||||
lf_printf(file, " \"%s\",\n", fields[insn_nmemonic]);
|
lf_printf(file, " \"%s\",\n", fields[insn_mnemonic]);
|
||||||
lf_printf(file, " \"%s\",\n", fields[insn_name]);
|
lf_printf(file, " \"%s\",\n", fields[insn_name]);
|
||||||
lf_printf(file, " },\n");
|
lf_printf(file, " },\n");
|
||||||
}
|
}
|
||||||
@ -2967,23 +3035,37 @@ gen_itable_c(insn_table *table, lf *file)
|
|||||||
/****************************************************************/
|
/****************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
model_h_function(insn_table *entry,
|
model_c_or_h_data(insn_table *table,
|
||||||
lf *file,
|
lf *file,
|
||||||
table_entry *function)
|
table_entry *data)
|
||||||
|
{
|
||||||
|
if (data->annex) {
|
||||||
|
table_entry_lf_c_line_nr(file, data);
|
||||||
|
lf_print_c_code(file, data->annex);
|
||||||
|
lf_print_lf_c_line_nr(file);
|
||||||
|
lf_printf(file, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
model_c_or_h_function(insn_table *entry,
|
||||||
|
lf *file,
|
||||||
|
table_entry *function,
|
||||||
|
char *prefix)
|
||||||
{
|
{
|
||||||
if (function->fields[function_type] == NULL
|
if (function->fields[function_type] == NULL
|
||||||
|| function->fields[function_type][0] == '\0') {
|
|| function->fields[function_type][0] == '\0') {
|
||||||
semantics_h_print_function(file,
|
error("Model function type not specified for %s", function->fields[function_name]);
|
||||||
function->fields[function_name],
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lf_printf(file, "\n");
|
lf_printf(file, "\n");
|
||||||
lf_printf(file, "INLINE_MODEL %s %s\n(%s);\n",
|
lf_printf(file, "%s %s %s\n(%s);\n",
|
||||||
|
prefix,
|
||||||
function->fields[function_type],
|
function->fields[function_type],
|
||||||
function->fields[function_name],
|
function->fields[function_name],
|
||||||
function->fields[function_param]);
|
function->fields[function_param]);
|
||||||
}
|
}
|
||||||
|
lf_printf(file, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -3001,10 +3083,8 @@ gen_model_h(insn_table *table, lf *file)
|
|||||||
lf_printf(file, "#define _MODEL_H_\n");
|
lf_printf(file, "#define _MODEL_H_\n");
|
||||||
lf_printf(file, "\n");
|
lf_printf(file, "\n");
|
||||||
|
|
||||||
if (model_macros) {
|
for(macro = model_macros; macro; macro = macro->next) {
|
||||||
for(macro = model_macros; macro; macro = macro->next)
|
model_c_or_h_data(table, file, insn_ptr->file_entry);
|
||||||
lf_printf(file, "%s\n", macro->file_entry->fields[insn_comment]);
|
|
||||||
lf_printf(file, "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lf_printf(file, "#ifndef INLINE_MODEL\n");
|
lf_printf(file, "#ifndef INLINE_MODEL\n");
|
||||||
@ -3090,7 +3170,7 @@ gen_model_h(insn_table *table, lf *file)
|
|||||||
lf_printf(file, "(const char *name);\n");
|
lf_printf(file, "(const char *name);\n");
|
||||||
|
|
||||||
for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
|
for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
|
||||||
model_h_function(table, file, insn_ptr->file_entry);
|
model_c_or_h_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
|
||||||
lf_printf(file, "\n");
|
lf_printf(file, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3100,8 +3180,8 @@ gen_model_h(insn_table *table, lf *file)
|
|||||||
|
|
||||||
/****************************************************************/
|
/****************************************************************/
|
||||||
|
|
||||||
typedef struct _model_c_data model_c_data;
|
typedef struct _model_c_passed_data model_c_passed_data;
|
||||||
struct _model_c_data {
|
struct _model_c_passed_data {
|
||||||
lf *file;
|
lf *file;
|
||||||
model *model_ptr;
|
model *model_ptr;
|
||||||
};
|
};
|
||||||
@ -3111,7 +3191,7 @@ model_c_insn(insn_table *entry,
|
|||||||
void *data,
|
void *data,
|
||||||
insn *instruction)
|
insn *instruction)
|
||||||
{
|
{
|
||||||
model_c_data *data_ptr = (model_c_data *)data;
|
model_c_passed_data *data_ptr = (model_c_passed_data *)data;
|
||||||
lf *file = data_ptr->file;
|
lf *file = data_ptr->file;
|
||||||
char *current_name = data_ptr->model_ptr->name;
|
char *current_name = data_ptr->model_ptr->name;
|
||||||
table_model_entry *model_ptr = instruction->file_entry->model_first;
|
table_model_entry *model_ptr = instruction->file_entry->model_first;
|
||||||
@ -3123,7 +3203,7 @@ model_c_insn(insn_table *entry,
|
|||||||
for(i = insn_model_unit; i < nr_insn_model_table_fields; i++) {
|
for(i = insn_model_unit; i < nr_insn_model_table_fields; i++) {
|
||||||
lf_printf(file, " %s,", model_ptr->fields[i]);
|
lf_printf(file, " %s,", model_ptr->fields[i]);
|
||||||
}
|
}
|
||||||
lf_printf(file, " },\n");
|
lf_printf(file, " }, /* %s */\n", instruction->file_entry->fields[insn_name]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3136,17 +3216,17 @@ model_c_insn(insn_table *entry,
|
|||||||
static void
|
static void
|
||||||
model_c_function(insn_table *table,
|
model_c_function(insn_table *table,
|
||||||
lf *file,
|
lf *file,
|
||||||
table_entry *function)
|
table_entry *function,
|
||||||
|
const char *prefix)
|
||||||
{
|
{
|
||||||
if (function->fields[function_type] == NULL
|
if (function->fields[function_type] == NULL
|
||||||
|| function->fields[function_type][0] == '\0') {
|
|| function->fields[function_type][0] == '\0') {
|
||||||
lf_print_c_semantic_function_header(file,
|
error("Model function return type not specified for %s", function->fields[function_name]);
|
||||||
function->fields[function_name],
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lf_printf(file, "\n");
|
lf_printf(file, "\n");
|
||||||
lf_printf(file, "INLINE_MODEL %s\n%s(%s)\n",
|
lf_printf(file, "%s %s\n%s(%s)\n",
|
||||||
|
prefix,
|
||||||
function->fields[function_type],
|
function->fields[function_type],
|
||||||
function->fields[function_name],
|
function->fields[function_name],
|
||||||
function->fields[function_param]);
|
function->fields[function_param]);
|
||||||
@ -3160,6 +3240,7 @@ model_c_function(insn_table *table,
|
|||||||
}
|
}
|
||||||
lf_printf(file, "}\n");
|
lf_printf(file, "}\n");
|
||||||
lf_print_lf_c_line_nr(file);
|
lf_print_lf_c_line_nr(file);
|
||||||
|
lf_printf(file, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -3178,6 +3259,14 @@ gen_model_c(insn_table *table, lf *file)
|
|||||||
lf_printf(file, "#include \"cpu.h\"\n");
|
lf_printf(file, "#include \"cpu.h\"\n");
|
||||||
lf_printf(file, "\n");
|
lf_printf(file, "\n");
|
||||||
|
|
||||||
|
for(insn_ptr = model_data; insn_ptr; insn_ptr = insn_ptr->next) {
|
||||||
|
model_c_or_h_data(table, file, insn_ptr->file_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
|
||||||
|
model_c_or_h_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
|
||||||
|
}
|
||||||
|
|
||||||
lf_printf(file, "/* map model enumeration into printable string */\n");
|
lf_printf(file, "/* map model enumeration into printable string */\n");
|
||||||
lf_printf(file, "const char *model_name[ (int)nr_models ] = {\n");
|
lf_printf(file, "const char *model_name[ (int)nr_models ] = {\n");
|
||||||
lf_printf(file, " \"NONE\",\n");
|
lf_printf(file, " \"NONE\",\n");
|
||||||
@ -3230,7 +3319,7 @@ gen_model_c(insn_table *table, lf *file)
|
|||||||
|
|
||||||
lf_printf(file, "/* Insn functional unit info */\n");
|
lf_printf(file, "/* Insn functional unit info */\n");
|
||||||
for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
|
for(model_ptr = models; model_ptr; model_ptr = model_ptr->next) {
|
||||||
model_c_data data;
|
model_c_passed_data data;
|
||||||
|
|
||||||
lf_printf(file, "static const model_time model_time_%s[] = {\n", model_ptr->name);
|
lf_printf(file, "static const model_time model_time_%s[] = {\n", model_ptr->name);
|
||||||
data.file = file;
|
data.file = file;
|
||||||
@ -3252,9 +3341,12 @@ gen_model_c(insn_table *table, lf *file)
|
|||||||
lf_printf(file, "};\n");
|
lf_printf(file, "};\n");
|
||||||
lf_printf(file, "\n");
|
lf_printf(file, "\n");
|
||||||
|
|
||||||
|
for(insn_ptr = model_internal; insn_ptr; insn_ptr = insn_ptr->next) {
|
||||||
|
model_c_function(table, file, insn_ptr->file_entry, "STATIC_INLINE_MODEL");
|
||||||
|
}
|
||||||
|
|
||||||
for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
|
for(insn_ptr = model_functions; insn_ptr; insn_ptr = insn_ptr->next) {
|
||||||
model_c_function(table, file, insn_ptr->file_entry);
|
model_c_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
|
||||||
lf_printf(file, "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lf_printf(file, "INLINE_MODEL void\n");
|
lf_printf(file, "INLINE_MODEL void\n");
|
||||||
|
@ -73,7 +73,7 @@ zalloc(long size)
|
|||||||
void *memory = malloc(size);
|
void *memory = malloc(size);
|
||||||
if (memory == NULL)
|
if (memory == NULL)
|
||||||
error("zmalloc failed\n");
|
error("zmalloc failed\n");
|
||||||
bzero(memory, size);
|
memset(memory, 0, size);
|
||||||
return memory;
|
return memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user