checkpoint

This commit is contained in:
Michael Meissner 1995-11-13 16:07:30 +00:00
parent 125d37c471
commit 1dc7c0ed84
8 changed files with 894 additions and 406 deletions

View File

@ -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>
* 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: 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
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
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
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
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.
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,
debug.c: Add tracing of load/store unit (virtual) with -t
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
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
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
one expands all mtspr/mfspr and branch instructions. Appears to

View File

@ -72,6 +72,7 @@ BSWAP_CFLAGS = @sim_bswap@
ENDIAN_CFLAGS = @sim_endian@
HOSTENDIAN_CFLAGS = @sim_hostendian@
SMP_CFLAGS = @sim_smp@
XOR_ENDIAN_CFLAGS = @sim_xor_endian@
BITSIZE_CFLAGS = @sim_bitsize@
HOSTBITSIZE_CFLAGS = @sim_hostbitsize@
ENV_CFLAGS = @sim_env@
@ -89,6 +90,7 @@ CONFIG_CFLAGS = $(BSWAP_CFLAGS) \
$(ENDIAN_CFLAGS) \
$(HOSTENDIAN_CFLAGS) \
$(SMP_CFLAGS) \
$(XOR_ENDIAN_CFLAGS) \
$(BITSIZE_CFLAGS) \
$(HOSTBITSIZE_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)
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)

View File

@ -16,7 +16,7 @@ fi],[sim_cflags=""])dnl
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],
[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";;
*) sim_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
esac
@ -125,7 +125,7 @@ AC_ARG_ENABLE(sim-inline,
[ --enable-sim-inline=inlines Specify which functions should be inlined.],
[sim_inline=""
case "$enableval" in
no) sim_inline="";;
no) sim_inline="-DDEFAULT_INLINE=0 -DINLINE=";;
0) sim_inline="-DDEFAULT_INLINE=0";;
yes | 2) sim_inline="-DDEFAULT_INLINE=2";;
1) sim_inline="-DDEFAULT_INLINE=1";;
@ -198,7 +198,7 @@ fi],[sim_hostendian=""])dnl
AC_ARG_ENABLE(sim-smp,
[ --enable-sim-smp=n Specify number of processors to configure for.],
[case "${enableval}" in
yes) sim_smp="-DWITH_SMP=2";;
yes) sim_smp="-DWITH_SMP=5";;
no) sim_smp="-DWITH_SMP=0";;
*) sim_smp="-DWITH_SMP=$enableval";;
esac
@ -209,6 +209,14 @@ if test x"$silent" != x"yes"; then
echo "Setting smp flags = $sim_smp" 6>&1
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,
[ --enable-sim-bitsize=n Specify target bitsize (32 or 64).],
[case "${enableval}" in
@ -377,6 +385,7 @@ AC_SUBST(sim_icache)
AC_SUBST(sim_inline)
AC_SUBST(sim_bswap)
AC_SUBST(sim_endian)
AC_SUBST(sim_xor_endian)
AC_SUBST(sim_hostendian)
AC_SUBST(sim_smp)
AC_SUBST(sim_bitsize)

View File

@ -464,43 +464,49 @@ device_tree_dump(device_tree *device,
/* Parse a device name, various formats */
#define SCAN_INIT(START, END, COUNT, NAME) \
char *START = NULL; \
char *END = strchr(NAME, '@'); \
int COUNT = 0; \
if (END == NULL) \
return 0; \
#define SCAN_INIT(NAME) \
char *START = (char*)0; \
char *END = (char*)0; \
int COUNT = -1; \
/* find the first element */ \
END = strchr(NAME, '@'); \
if (END == (char*)0) \
return COUNT; \
COUNT += 1; \
START = END + 1
#define SCAN_U(START, END, COUNT, U) \
#define SCAN_END \
return COUNT
#define SCAN_U(U) \
do { \
*U = strtoul(START, &END, 0); \
if (START == END) \
return COUNT; \
COUNT++; \
COUNT += 1; \
if (*END != ',') \
return COUNT; \
START = END + 1; \
} while (0)
#define SCAN_P(START, END, COUNT, P) \
#define SCAN_P(P) \
do { \
*P = (void*)(unsigned)strtouq(START, &END, 0); \
*P = (void*)(unsigned)strtouq(START, END, 0); \
if (START == END) \
return COUNT; \
COUNT++; \
COUNT += 1; \
if (*END != ',') \
return COUNT; \
START = END + 1; \
} while (0)
#define SCAN_C(START, END, COUNT, C, SIZE) \
#define SCAN_C(C, SIZE) \
do { \
char *chp = C; \
END = START; \
while (*END != '\0' && *END != ',') { \
if (*END == '\\') \
END++; \
END += 1; \
*chp = *END; \
chp += 1; \
END += 1; \
@ -510,19 +516,55 @@ do { \
*chp = '\0'; \
if (START == END) \
return COUNT; \
COUNT++; \
COUNT += 1; \
if (*END != ',') \
return COUNT; \
START = END + 1; \
} 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
scand_uw(const char *name,
unsigned_word *uw1)
{
SCAN_INIT(start, end, count, name);
SCAN_U(start, end, count, uw1);
return count;
SCAN_INIT(name);
SCAN_U(uw1);
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
@ -530,10 +572,10 @@ scand_uw_u(const char *name,
unsigned_word *uw1,
unsigned *u2)
{
SCAN_INIT(start, end, count, name);
SCAN_U(start, end, count, uw1);
SCAN_U(start, end, count, u2);
return count;
SCAN_INIT(name);
SCAN_U(uw1);
SCAN_U(u2);
SCAN_END;
}
INLINE_DEVICE_TREE int
@ -542,11 +584,22 @@ scand_uw_u_u(const char *name,
unsigned *u2,
unsigned *u3)
{
SCAN_INIT(start, end, count, name);
SCAN_U(start, end, count, uw1);
SCAN_U(start, end, count, u2);
SCAN_U(start, end, count, u3);
return count;
SCAN_INIT(name);
SCAN_U(uw1);
SCAN_U(u2);
SCAN_U(u3);
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
@ -555,33 +608,46 @@ scand_uw_uw_u(const char *name,
unsigned_word *uw2,
unsigned *u3)
{
SCAN_INIT(start, end, count, name);
SCAN_U(start, end, count, uw1);
SCAN_U(start, end, count, uw2);
SCAN_U(start, end, count, u3);
return count;
SCAN_INIT(name);
SCAN_U(uw1);
SCAN_U(uw2);
SCAN_U(u3);
SCAN_END;
}
INLINE_DEVICE_TREE int
scand_c(const char *name,
char *c1, int c1size)
scand_uw_uw_u_u_c(const char *name,
unsigned_word *uw1,
unsigned_word *uw2,
unsigned *u3,
unsigned *u4,
char *c5,
unsigned c5size)
{
SCAN_INIT(start, end, count, name);
SCAN_C(start, end, count, c1, c1size);
return count;
SCAN_INIT(name);
SCAN_U(uw1);
SCAN_U(uw2);
SCAN_U(u3);
SCAN_U(u4);
SCAN_C(c5, c5size);
SCAN_END;
}
INLINE_DEVICE_TREE int
scand_c_uw_u(const char *name,
char *c1, int c1size,
unsigned_word *uw2,
unsigned *u3)
scand_uw_uw_u_u_u(const char *name,
unsigned_word *uw1,
unsigned_word *uw2,
unsigned *u3,
unsigned *u4,
unsigned *u5)
{
SCAN_INIT(start, end, count, name);
SCAN_C(start, end, count, c1, c1size);
SCAN_U(start, end, count, uw2);
SCAN_U(start, end, count, u3);
return count;
SCAN_INIT(name);
SCAN_U(uw1);
SCAN_U(uw2);
SCAN_U(u3);
SCAN_U(u4);
SCAN_U(u5);
SCAN_END;
}
@ -633,6 +699,43 @@ enum {
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 *
printd_uw_u(const char *name,
unsigned_word uw1,
@ -711,41 +814,4 @@ printd_uw_u_u_c(const char *name,
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_ */

View File

@ -116,10 +116,28 @@ INLINE_DEVICE_TREE void device_tree_dump
u: unsigned
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
(const char *name,
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
(const char *name,
unsigned_word *uw1,
@ -131,21 +149,42 @@ INLINE_DEVICE_TREE int scand_uw_u_u
unsigned *u2,
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
(const char *name,
unsigned_word *uw1,
unsigned_word *uw2,
unsigned *u3);
INLINE_DEVICE_TREE int scand_c
INLINE_DEVICE_TREE int scand_uw_uw_u_u_c
(const char *name,
char *c1, int c1size);
INLINE_DEVICE_TREE int scand_c_uw_u
(const char *name,
char *c1, int c1size,
unsigned_word *uw1,
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
(const char *name,
@ -165,13 +204,4 @@ INLINE_DEVICE_TREE char *printd_uw_u_u_c
unsigned u3,
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_ */

View File

@ -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 */
@ -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
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;
return nr_bytes;
}
@ -438,7 +479,7 @@ console_io_write_buffer_callback(const device *me,
unsigned_word cia)
{
console_device *console = (console_device*)me->data;
unsigned_1 val = *(unsigned8*)source;
unsigned_1 val = *(unsigned_1*)source;
DTRACE_IO_WRITE_BUFFER(console);
switch ((int)addr) {
@ -529,7 +570,7 @@ icu_io_read_buffer_callback(const device *me,
unsigned_1 val;
DTRACE_IO_READ_BUFFER(icu);
val = cpu_nr(processor);
bzero(dest, nr_bytes);
memset(dest, 0, nr_bytes);
*(unsigned_1*)dest = val;
return nr_bytes;
}
@ -605,7 +646,7 @@ halt_io_write_buffer_callback(const device *me,
unsigned_word cia)
{
DTRACE_IO_WRITE_BUFFER(halt);
cpu_halt(processor, cia, was_exited, 0);
cpu_halt(processor, cia, was_exited, *(unsigned_1*)source);
return 0;
}
@ -820,7 +861,7 @@ vm_io_read_buffer_callback(const device *me,
{
DTRACE_IO_READ_BUFFER(vm);
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;
}
else
@ -1062,38 +1103,17 @@ file_init_callback(const device *me,
psim *system)
{
unsigned_word addr;
unsigned count;
char *file_name;
char buf;
FILE *image;
int count;
char file_name[1024];
DTRACE_INIT(file);
if ((file_name = strchr(me->name, ',')) == NULL
|| scand_uw(me->name, &addr) != 1)
error("file_init_callback() invalid file device %s\n", me->name);
/* open the file to load */
file_name++; /* skip the `,' */
image = fopen(file_name, "r");
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);
if (scand_uw_c(me->name, &addr, file_name, sizeof(file_name)) != 2)
error("devices/file - Usage: file@<address>,<file-name>\n");
/* load the file */
count = dma_file(me, file_name, addr);
if (count < 0)
error("devices/%s - Problem loading file %s\n", me->name, file_name);
}
@ -1114,8 +1134,9 @@ static device_callbacks const file_callbacks = {
/* HTAB: htab@0x<address>,<nr_bytes>
PTE: pte@0x<effective-address>,0x<real-address>,<nr_bytes>
/* HTAB: htab@<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.
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)
{
DTRACE_INIT(htab);
if (WITH_TARGET_WORD_BITSIZE != 32)
error("devices/htab: only 32bit targets currently suported\n");
/* only the pte does work */
if (strncmp(me->name, "pte@", strlen("pte@")) == 0) {
unsigned_word htab_ra;
unsigned32 htab_ra;
unsigned htab_nr_bytes;
unsigned_word pte_ea;
unsigned_word pte_ra;
signed32 pte_va; /* so that 0xff...0 is make 0xffffff00 */
unsigned32 pte_ra;
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 */
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)
error("htab_init_callback() htab entry %s invalid\n",
error("devices/%s - Usage: htab@<real-addr>,<nr_bytes>\n",
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 */
if (scand_uw_uw_u(me->name, &pte_ea, &pte_ra, &pte_nr_bytes) != 3)
error("htab_init_callback() pte entry %s invalid\n", me->name);
error("Map ea=0x%x, ra=0x%x, nr_bytes=%d using htab=0x%x, nr_bytes=%d\n",
pte_ea, pte_ra, pte_nr_bytes, htab_ra, htab_nr_bytes);
if (scand_uw_uw_u_u_u(me->name, &pte_va, &pte_ra,
&pte_wimg, &pte_pp, &pte_nr_bytes) != 5) {
int 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,
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,
psim *system)
{
char file_name[100];
char file_name[1024];
bfd *image;
DTRACE_INIT(binary);
/* get a file name */
if (scand_c(me->name, file_name, sizeof(file_name)) != 1)
error("load_binary_init_callback() invalid load-binary device %s\n",
me->name);
error("devices/binary - Usage: binary@<file-name>\n");
/* open the file */
image = bfd_openr(file_name, NULL);
if (image == NULL) {
bfd_perror("open failed:");
error("nothing loaded\n");
bfd_perror("devices/binary");
error("devices/%s - the file %s not loaded\n", me->name, file_name);
}
/* check it is valid */

View File

@ -513,16 +513,6 @@ struct _opcode_field {
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
dump_opcode_field(opcode_field *field, int indent, int levels)
{
@ -575,7 +565,7 @@ typedef enum {
insn_format,
insn_form,
insn_flags,
insn_nmemonic,
insn_mnemonic,
insn_name,
insn_comment,
nr_insn_table_fields
@ -588,7 +578,8 @@ typedef enum {
} function_table_fields;
typedef enum {
model_name = insn_nmemonic,
model_default = insn_form,
model_name = insn_mnemonic,
model_identifer = insn_name,
model_func = insn_comment,
} model_table_fields;
@ -654,6 +645,12 @@ static insn *last_model_macro;
static insn *model_functions;
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
insn_table_insert_function(insn_table *table,
table_entry *file_entry)
@ -670,159 +667,6 @@ insn_table_insert_function(insn_table *table,
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
insn_table_insert_insn(insn_table *table,
table_entry *file_entry,
@ -877,11 +721,12 @@ insn_table_find_opcode_field(insn *insns,
opcode_rules *rule,
int string_only)
{
opcode_field *curr_opcode = opcode_field_new();
opcode_field *curr_opcode = ZALLOC(opcode_field);
insn *entry;
ASSERT(rule);
curr_opcode->first = insn_size;
curr_opcode->last = -1;
for (entry = insns; entry != NULL; entry = entry->next) {
insn_fields *fields = entry->fields;
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 *
insn_table_load_insns(char *file_name)
@ -1139,10 +1125,16 @@ insn_table_load_insns(char *file_name)
model_table_insert(table, file_entry);
}
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])) {
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 {
insn_fields *fields;
@ -1367,6 +1359,7 @@ lf_print_idecode_table(lf *file,
lf_printf(file, "while (1) {\n");
lf_indent(file, +2);
{
lf_printf(file, "/* nonzero mask -> another table */\n");
lf_printf(file, "while (table_entry->mask != 0) {\n");
lf_indent(file, +2);
{
@ -1378,24 +1371,26 @@ lf_print_idecode_table(lf *file,
}
lf_indent(file, -2);
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, " table_entry->function_or_table)\n");
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) {
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, "table = ((idecode_table_entry*)\n");
lf_printf(file, " table_entry->function_or_table);\n");
@ -1616,9 +1611,11 @@ dump_traverse(insn_table *table)
static void
semantics_h_print_function(lf *file,
char *basename,
insn_bits *expanded_bits)
lf_print_semantic_function_header(lf *file,
char *basename,
insn_bits *expanded_bits,
int is_function_definition,
int is_inline_function)
{
lf_printf(file, "\n");
lf_printf(file, "STATIC_SEMANTICS unsigned_word ");
@ -1626,8 +1623,11 @@ semantics_h_print_function(lf *file,
basename,
expanded_bits,
function_name_prefix_semantics);
lf_printf(file, "\n(%s);\n",
lf_printf(file, "\n(%s)",
(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;
ASSERT(entry->nr_insn == 1);
semantics_h_print_function(file,
entry->insns->file_entry->fields[insn_name],
entry->expanded_bits);
lf_print_semantic_function_header(file,
entry->insns->file_entry->fields[insn_name],
entry->expanded_bits,
0/* isnt function definition*/,
!idecode_cache && entry->parent->opcode_rule->use_switch);
}
static void
@ -1649,9 +1651,11 @@ semantics_h_insn(insn_table *entry,
insn *instruction)
{
lf *file = (lf*)data;
semantics_h_print_function(file,
instruction->file_entry->fields[insn_name],
NULL);
lf_print_semantic_function_header(file,
instruction->file_entry->fields[insn_name],
NULL,
0/*isnt function definition*/,
0/*isnt inline function*/);
}
static void
@ -1662,9 +1666,11 @@ semantics_h_function(insn_table *entry,
lf *file = (lf*)data;
if (function->fields[function_type] == NULL
|| function->fields[function_type][0] == '\0') {
semantics_h_print_function(file,
function->fields[function_name],
NULL);
lf_print_semantic_function_header(file,
function->fields[function_name],
NULL,
0/*isnt function definition*/,
1/*is inline function*/);
}
else {
lf_printf(file, "\n");
@ -2280,13 +2286,16 @@ static void
lf_print_c_semantic_function(lf *file,
insn *instruction,
insn_bits *expanded_bits,
opcode_field *opcodes)
opcode_field *opcodes,
int is_inline_function)
{
/* build the semantic routine to execute the instruction */
lf_print_c_semantic_function_header(file,
instruction->file_entry->fields[insn_name],
expanded_bits);
lf_print_semantic_function_header(file,
instruction->file_entry->fields[insn_name],
expanded_bits,
1/*is-function-definition*/,
is_inline_function);
lf_print_c_semantic(file,
instruction,
expanded_bits,
@ -2307,7 +2316,8 @@ semantics_c_leaf(insn_table *entry,
lf_print_c_semantic_function(file,
entry->insns,
entry->expanded_bits,
entry->parent->opcode);
entry->parent->opcode,
!idecode_cache && entry->parent->opcode_rule->use_switch);
}
static void
@ -2317,7 +2327,8 @@ semantics_c_insn(insn_table *table,
{
lf *file = (lf*)data;
lf_print_c_semantic_function(file, instruction,
NULL, NULL);
NULL, NULL,
0/*isnt_inline_function*/);
}
static void
@ -2328,9 +2339,11 @@ semantics_c_function(insn_table *table,
lf *file = (lf*)data;
if (function->fields[function_type] == NULL
|| function->fields[function_type][0] == '\0') {
lf_print_c_semantic_function_header(file,
function->fields[function_name],
NULL);
lf_print_semantic_function_header(file,
function->fields[function_name],
NULL,
1/*is function definition*/,
1/*is inline function*/);
}
else {
lf_printf(file, "\n");
@ -2468,7 +2481,7 @@ idecode_table_leaf(insn_table *entry,
}
else if (entry->opcode_rule->use_switch) {
/* table calling switch statement */
lf_printf(file, " /*%d*/ { -1, 0, ",
lf_printf(file, " /*%d*/ { 0, 0, ",
entry->opcode_nr);
lf_print_table_name(file, entry);
lf_printf(file, " },\n");
@ -2552,8 +2565,13 @@ idecode_switch_leaf(insn_table *entry,
ASSERT(entry->parent != NULL);
ASSERT(depth == 0);
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);
{
if (entry->opcode == NULL) {
@ -2575,8 +2593,7 @@ idecode_switch_leaf(insn_table *entry,
lf_print_idecode_switch(file, entry);
}
else {
/* switch calling table */
lf_printf(file, "return ");
/* switch looking up a table */
lf_print_idecode_table(file, entry);
}
lf_printf(file, "break;\n");
@ -2602,8 +2619,10 @@ idecode_switch_end(insn_table *table,
lf *file = (lf*)data;
ASSERT(depth == 0);
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_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
idecode_expand_if_switch(insn_table *table,
void *data,
@ -2652,11 +2712,9 @@ idecode_expand_if_switch(insn_table *table,
if (table->opcode_rule->use_switch
&& table->parent != NULL /* don't expand the top one yet */
&& !table->parent->opcode_rule->use_switch) {
lf_printf(file, "\n");
lf_printf(file, "STATIC_INLINE_IDECODE void\n");
lf_print_table_name(file, table);
lf_printf(file, "\n(%s)\n",
(idecode_cache ? cache_idecode_formal : semantic_formal));
lf_print_idecode_switch_function_header(file,
table,
1/*is function definition*/);
lf_printf(file, "{\n");
{
lf_indent(file, +2);
@ -2672,7 +2730,8 @@ static void
lf_print_c_cracker_function(lf *file,
insn *instruction,
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 */
lf_printf(file, "\n");
@ -2698,11 +2757,13 @@ idecode_crack_leaf(insn_table *entry,
ASSERT(entry->nr_insn == 1
&& entry->opcode == NULL
&& entry->parent != NULL
&& entry->parent->opcode != NULL);
&& entry->parent->opcode != NULL
&& entry->parent->opcode_rule != NULL);
lf_print_c_cracker_function(file,
entry->insns,
entry->expanded_bits,
entry->opcode);
entry->opcode,
entry->parent->opcode_rule->use_switch);
}
static void
@ -2714,7 +2775,8 @@ idecode_crack_insn(insn_table *entry,
lf_print_c_cracker_function(file,
instruction,
NULL,
NULL);
NULL,
0/*isnt inline function*/);
}
static void
@ -2812,6 +2874,12 @@ gen_idecode_c(insn_table *table, lf *file)
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 */
for (depth = insn_table_depth(table);
@ -2850,7 +2918,7 @@ gen_idecode_c(insn_table *table, lf *file)
lf_indent(file, -2);
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 *form;\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, "} itable_info;\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_form]);
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, " },\n");
}
@ -2967,23 +3035,37 @@ gen_itable_c(insn_table *table, lf *file)
/****************************************************************/
static void
model_h_function(insn_table *entry,
lf *file,
table_entry *function)
model_c_or_h_data(insn_table *table,
lf *file,
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
|| function->fields[function_type][0] == '\0') {
semantics_h_print_function(file,
function->fields[function_name],
NULL);
error("Model function type not specified for %s", function->fields[function_name]);
}
else {
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_name],
function->fields[function_param]);
}
lf_printf(file, "\n");
}
static void
@ -3001,10 +3083,8 @@ gen_model_h(insn_table *table, lf *file)
lf_printf(file, "#define _MODEL_H_\n");
lf_printf(file, "\n");
if (model_macros) {
for(macro = model_macros; macro; macro = macro->next)
lf_printf(file, "%s\n", macro->file_entry->fields[insn_comment]);
lf_printf(file, "\n");
for(macro = model_macros; macro; macro = macro->next) {
model_c_or_h_data(table, file, insn_ptr->file_entry);
}
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");
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");
}
@ -3100,8 +3180,8 @@ gen_model_h(insn_table *table, lf *file)
/****************************************************************/
typedef struct _model_c_data model_c_data;
struct _model_c_data {
typedef struct _model_c_passed_data model_c_passed_data;
struct _model_c_passed_data {
lf *file;
model *model_ptr;
};
@ -3111,7 +3191,7 @@ model_c_insn(insn_table *entry,
void *data,
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;
char *current_name = data_ptr->model_ptr->name;
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++) {
lf_printf(file, " %s,", model_ptr->fields[i]);
}
lf_printf(file, " },\n");
lf_printf(file, " }, /* %s */\n", instruction->file_entry->fields[insn_name]);
return;
}
@ -3136,17 +3216,17 @@ model_c_insn(insn_table *entry,
static void
model_c_function(insn_table *table,
lf *file,
table_entry *function)
table_entry *function,
const char *prefix)
{
if (function->fields[function_type] == NULL
|| function->fields[function_type][0] == '\0') {
lf_print_c_semantic_function_header(file,
function->fields[function_name],
NULL);
error("Model function return type not specified for %s", function->fields[function_name]);
}
else {
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_name],
function->fields[function_param]);
@ -3160,6 +3240,7 @@ model_c_function(insn_table *table,
}
lf_printf(file, "}\n");
lf_print_lf_c_line_nr(file);
lf_printf(file, "\n");
}
static void
@ -3178,6 +3259,14 @@ gen_model_c(insn_table *table, lf *file)
lf_printf(file, "#include \"cpu.h\"\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, "const char *model_name[ (int)nr_models ] = {\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");
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);
data.file = file;
@ -3252,9 +3341,12 @@ gen_model_c(insn_table *table, lf *file)
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) {
model_c_function(table, file, insn_ptr->file_entry);
lf_printf(file, "\n");
model_c_function(table, file, insn_ptr->file_entry, "INLINE_MODEL");
}
lf_printf(file, "INLINE_MODEL void\n");

View File

@ -73,7 +73,7 @@ zalloc(long size)
void *memory = malloc(size);
if (memory == NULL)
error("zmalloc failed\n");
bzero(memory, size);
memset(memory, 0, size);
return memory;
}