* RFA: contribute Renesas M32C sim
@ 2005-10-07 20:46 Jim Blandy
2005-10-07 21:03 ` Daniel Jacobowitz
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Jim Blandy @ 2005-10-07 20:46 UTC (permalink / raw)
To: gdb-patches
DJ Delorie is the target maintainer for the M32C, so the rules in
sim/MAINTAINERS make him the maintainer of this sim by default.
sim/ChangeLog:
2005-10-06 Jim Blandy <jimb@redhat.com>
Add simulator for Renesas M32C and M16C.
* m32c: New directory.
* configure.ac: Add entry for Renesas M32C.
* configure: Regenerate.
sim/m32c/ChangeLog:
2005-10-06 Jim Blandy <jimb@redhat.com>
Simulator for Renesas M32C and M16C, by DJ Delorie <dj@redhat.com>,
with further work from Jim Blandy <jimb@redhat.com> and
Kevin Buettner <kevinb@redhat.com>.
* ChangeLog: New.
* Makefile.in: New.
* blinky.S: New.
* config.in: New.
* configure: New.
* configure.in: New.
* cpu.h: New.
* gdb-if.c: New.
* gloss.S: New.
* int.c: New.
* int.h: New.
* load.c: New.
* load.h: New.
* m32c.opc: New.
* main.c: New.
* mem.c: New.
* mem.h: New.
* misc.c: New.
* misc.h: New.
* opc2c.c: New.
* r8c.opc: New.
* reg.c: New.
* run-m32c.cc: New.
* safe-fgets.c: New.
* safe-fgets.h: New.
* sample.S: New.
* sample.ld: New.
* sample2.c: New.
* srcdest.c: New.
* syscalls.c: New.
* syscalls.h: New.
* trace.c: New.
* trace.h: New.
Index: sim/configure.ac
===================================================================
RCS file: /cvs/src/src/sim/configure.ac,v
retrieving revision 1.7
diff -c -p -r1.7 configure.ac
*** sim/configure.ac 17 May 2005 14:11:24 -0000 1.7
--- sim/configure.ac 6 Oct 2005 22:36:51 -0000
*************** if test "${enable_sim}" != no; then
*** 73,78 ****
--- 73,82 ----
testsuite=yes
common=yes
;;
+ m32c-*-*)
+ AC_CONFIG_SUBDIRS(m32c)
+ common=yes
+ ;;
m32r-*-*)
AC_CONFIG_SUBDIRS(m32r)
testsuite=yes
Index: sim/m32c/Makefile.in
===================================================================
RCS file: sim/m32c/Makefile.in
diff -N sim/m32c/Makefile.in
*** sim/m32c/Makefile.in 1 Jan 1970 00:00:00 -0000
--- sim/m32c/Makefile.in 6 Oct 2005 22:36:51 -0000
***************
*** 0 ****
--- 1,72 ----
+
+ ## COMMON_PRE_CONFIG_FRAG
+
+ SIM_EXTRA_CFLAGS = -Wall
+
+ SIM_RUN_OBJS = \
+ main.o \
+ $(ENDLIST)
+
+ SIM_OBJS = \
+ gdb-if.o \
+ int.o \
+ load.o \
+ mem.o \
+ misc.o \
+ reg.o \
+ r8c.o \
+ m32c.o \
+ srcdest.o \
+ syscalls.o \
+ trace.o \
+ $(ENDLIST)
+
+ # SIM_EXTRA_ALL = sample.x sample2.x
+
+ LIBS = $B/bfd/libbfd.a $B/libiberty/libiberty.a
+
+ ## COMMON_POST_CONFIG_FRAG
+
+ arch = m32c
+
+ r8c.c : r8c.opc opc2c
+ ./opc2c -l r8c.out $(srcdir)/r8c.opc > r8c.c
+
+ m32c.c : m32c.opc opc2c
+ ./opc2c -l m32c.out $(srcdir)/m32c.opc > m32c.c
+
+ opc2c : opc2c.o safe-fgets.o
+ $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
+
+ sample.x : $(srcdir)/sample.S $(srcdir)/sample.ld
+ ../../gcc/xgcc $(CPUFLAGS) -B../../gcc/ -c $(srcdir)/sample.S -o sample.o
+ ../../ld/ld-new sample.o -o sample.x -T$(srcdir)/sample.ld
+
+ sample.mot : sample.x
+ ../../binutils/objcopy --srec-forceS3 -O srec sample.x sample.mot
+
+ sample2.x : sample2.o gloss.o $(srcdir)/sample.ld
+ ../../ld/ld-new sample2.o gloss.o -o sample2.x -T$(srcdir)/sample.ld
+
+ sample2.o : $(srcdir)/sample2.c
+ ../../gcc/xgcc $(CPUFLAGS) -B../../gcc/ -c $(srcdir)/sample2.c -o sample2.o
+
+ gloss.o : $(srcdir)/gloss.S
+ ../../gcc/xgcc $(CPUFLAGS) -B../../gcc/ -c $(srcdir)/gloss.S -o gloss.o
+
+ encodings:
+ grep '/\* [01]' $(srcdir)/r8c.opc | sort
+
+ gdb-if.o : cpu.h mem.h load.h syscalls.h
+ int.o : int.h cpu.h mem.h
+ load.o : load.h cpu.h mem.h
+ main.o : cpu.h mem.h misc.h load.h
+ mem.o : mem.h cpu.h syscalls.h
+ misc.o : cpu.h misc.h
+ opc2c.o : safe-fgets.h
+ reg.o : cpu.h
+ safe-fgets.o : safe-fgets.h
+ srcdest.c : cpu.h mem.h
+ syscalls.c : cpu.h mem.h syscalls.h
+
+ r8c.o : cpu.h mem.h misc.h int.h
Index: sim/m32c/blinky.S
===================================================================
RCS file: sim/m32c/blinky.S
diff -N sim/m32c/blinky.S
*** sim/m32c/blinky.S 1 Jan 1970 00:00:00 -0000
--- sim/m32c/blinky.S 6 Oct 2005 22:36:51 -0000
***************
*** 0 ****
--- 1,14 ----
+ .text
+
+ .global _start
+ _start:
+ mov.w #0xe1,a0
+ top:
+ sub.w #1,r0
+ mov.b r0h,[a0]
+
+ mov.w #1000,r1
+ loop:
+ adjnz.w #-1,r1,loop
+
+ jmp.w top
Index: sim/m32c/config.in
===================================================================
RCS file: sim/m32c/config.in
diff -N sim/m32c/config.in
Index: sim/m32c/configure.in
===================================================================
RCS file: sim/m32c/configure.in
diff -N sim/m32c/configure.in
*** sim/m32c/configure.in 1 Jan 1970 00:00:00 -0000
--- sim/m32c/configure.in 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,12 ----
+ dnl Process this file with autoconf to produce a configure script.
+ AC_PREREQ(2.5)dnl
+ AC_INIT(Makefile.in)
+ AC_CONFIG_HEADER(config.h:config.in)
+
+ sinclude(../common/aclocal.m4)
+
+ # Bugs in autoconf 2.59 break the call to SIM_AC_COMMON, hack around
+ # it by inlining the macro's contents.
+ sinclude(../common/common.m4)
+
+ SIM_AC_OUTPUT
Index: sim/m32c/cpu.h
===================================================================
RCS file: sim/m32c/cpu.h
diff -N sim/m32c/cpu.h
*** sim/m32c/cpu.h 1 Jan 1970 00:00:00 -0000
--- sim/m32c/cpu.h 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,196 ----
+ extern int verbose;
+ extern int trace;
+ extern int enable_counting;
+
+ typedef unsigned char QI;
+ typedef unsigned short HI;
+ typedef unsigned long SI;
+ typedef unsigned long long DI;
+
+ #define CPU_R8C 0x11
+ #define CPU_M16C 0x12
+ #define CPU_M32CM 0x23
+ #define CPU_M32C 0x24
+ extern int m32c_cpu;
+ void m32c_set_cpu (int cpu);
+
+ #define A16 (m32c_cpu & 0x10)
+ #define A24 (m32c_cpu & 0x20)
+
+ typedef struct {
+ HI r_r0;
+ HI r_r2;
+ HI r_r1;
+ HI r_r3;
+ SI r_a0;
+ SI r_a1;
+ SI r_sb;
+ SI r_fb;
+ } reg_bank_type;
+
+ typedef struct {
+ reg_bank_type r[2];
+ QI r_intbh;
+ HI r_intbl;
+ SI r_usp;
+ SI r_isp;
+ SI r_pc;
+ HI r_flags;
+ } regs_type;
+
+ extern regs_type regs;
+ extern int addr_mask;
+ extern int membus_mask;
+
+ #define FLAGBIT_C 0x0001
+ #define FLAGBIT_D 0x0002
+ #define FLAGBIT_Z 0x0004
+ #define FLAGBIT_S 0x0008
+ #define FLAGBIT_B 0x0010
+ #define FLAGBIT_O 0x0020
+ #define FLAGBIT_I 0x0040
+ #define FLAGBIT_U 0x0080
+
+ #define REG_BANK (regs.r_flags & FLAG_B ? 1 : 0)
+
+ typedef enum {
+ mem,
+ r0, r0h, r0l,
+ r1, r1h, r1l,
+ r2, r2r0,
+ r3, r3r1,
+ r3r1r2r0,
+ r3r2r1r0,
+ a0,
+ a1, a1a0,
+ sb, fb,
+ intb, intbl, intbh,
+ sp, usp, isp, pc, flags,
+ num_regs
+ } reg_id;
+
+ extern char *reg_names[];
+ extern int reg_bytes[];
+
+ extern unsigned int b2mask[];
+ extern unsigned int b2signbit[];
+ extern int b2maxsigned[];
+ extern int b2minsigned[];
+
+ void init_regs (void);
+ void stack_heap_stats (void);
+ void set_pointer_width (int bytes);
+ unsigned int get_reg (reg_id id);
+ DI get_reg_ll (reg_id id);
+ void put_reg (reg_id id, unsigned int value);
+ void put_reg_ll (reg_id id, DI value);
+
+ void set_flags (int mask, int newbits);
+ void set_oszc (int value, int bytes, int c);
+ void set_szc (int value, int bytes, int c);
+ void set_osz (int value, int bytes);
+ void set_sz (int value, int bytes);
+ void set_zc (int z, int c);
+ void set_c (int c);
+
+ const char *bits(int v, int b);
+
+ typedef struct {
+ QI bytes;
+ QI mem;
+ HI mask;
+ union {
+ unsigned int addr;
+ reg_id reg;
+ } u;
+ } srcdest;
+
+ void decode_indirect (int src_indirect, int dest_indirect);
+ void decode_index (int src_addend, int dest_addend);
+
+ /* r8c */
+ srcdest decode_srcdest4 (int destcode, int bw);
+ srcdest decode_dest3 (int destcode, int bw);
+ srcdest decode_src2 (int srccode, int bw, int d);
+ srcdest decode_dest1 (int destcode, int bw);
+ srcdest decode_jumpdest (int destcode, int w);
+ srcdest decode_cr (int crcode);
+ srcdest decode_cr_b (int crcode, int bank);
+ #define CR_B_DCT0 0
+ #define CR_B_INTB 1
+ #define CR_B_DMA0 2
+
+ /* m32c */
+ srcdest decode_dest23 (int ddd, int dd, int bytes);
+ srcdest decode_src23 (int sss, int ss, int bytes);
+ srcdest decode_src3 (int sss, int bytes);
+ srcdest decode_dest2 (int dd, int bytes);
+
+ srcdest widen_sd (srcdest sd);
+ srcdest reg_sd (reg_id reg);
+
+ /* Mask has the one appropriate bit set. */
+ srcdest decode_bit (int destcode);
+ srcdest decode_bit11 (int op0);
+ int get_bit (srcdest sd);
+ void put_bit (srcdest sd, int val);
+ int get_bit2 (srcdest sd, int bit);
+ void put_bit2 (srcdest sd, int bit, int val);
+
+ int get_src (srcdest sd);
+ void put_dest (srcdest sd, int value);
+
+ int condition_true (int cond_id);
+
+ #define FLAG(f) (regs.r_flags & f ? 1 : 0)
+ #define FLAG_C FLAG(FLAGBIT_C)
+ #define FLAG_D FLAG(FLAGBIT_D)
+ #define FLAG_Z FLAG(FLAGBIT_Z)
+ #define FLAG_S FLAG(FLAGBIT_S)
+ #define FLAG_B FLAG(FLAGBIT_B)
+ #define FLAG_O FLAG(FLAGBIT_O)
+ #define FLAG_I FLAG(FLAGBIT_I)
+ #define FLAG_U FLAG(FLAGBIT_U)
+
+ /* Instruction step return codes.
+ Suppose one of the decode_* functions below returns a value R:
+ - If M32C_STEPPED (R), then the single-step completed normally.
+ - If M32C_HIT_BREAK (R), then the program hit a breakpoint.
+ - If M32C_EXITED (R), then the program has done an 'exit' system
+ call, and the exit code is M32C_EXIT_STATUS (R).
+ - If M32C_STOPPED (R), then a signal (number M32C_STOP_SIG (R)) was
+ generated.
+
+ For building step return codes:
+ - M32C_MAKE_STEPPED is the return code for finishing a normal step.
+ - M32C_MAKE_HIT_BREAK is the return code for hitting a breakpoint.
+ - M32C_MAKE_EXITED (C) is the return code for exiting with status C.
+ - M32C_MAKE_STOPPED (S) is the return code for stopping on signal S. */
+ #define M32C_MAKE_STEPPED() (0)
+ #define M32C_MAKE_HIT_BREAK() (1)
+ #define M32C_MAKE_EXITED(c) (((int) (c) << 8) + 2)
+ #define M32C_MAKE_STOPPED(s) (((int) (s) << 8) + 3)
+
+ #define M32C_STEPPED(r) ((r) == M32C_MAKE_STEPPED ())
+ #define M32C_HIT_BREAK(r) ((r) == M32C_MAKE_HIT_BREAK ())
+ #define M32C_EXITED(r) (((r) & 0xff) == 2)
+ #define M32C_EXIT_STATUS(r) ((r) >> 8)
+ #define M32C_STOPPED(r) (((r) & 0xff) == 3)
+ #define M32C_STOP_SIG(r) ((r) >> 8)
+
+ /* The step result for the current step. Global to allow
+ communication between the stepping function and the system
+ calls. */
+ extern int step_result;
+
+ /* Used to detect heap/stack collisions */
+ extern unsigned int heaptop;
+ extern unsigned int heapbottom;
+
+ /* Points to one of the below functions, set by m32c_load(). */
+ extern int (*decode_opcode)();
+
+ extern int decode_r8c();
+ extern int decode_m32c();
+
+ extern void trace_register_changes ();
Index: sim/m32c/gdb-if.c
===================================================================
RCS file: sim/m32c/gdb-if.c
diff -N sim/m32c/gdb-if.c
*** sim/m32c/gdb-if.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/gdb-if.c 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,611 ----
+ /* gdb.c --- sim interface to GDB. */
+
+ #include <stdio.h>
+ #include <assert.h>
+ #include <signal.h>
+ #include <string.h>
+ #include <ctype.h>
+
+ #include "ansidecl.h"
+ #include "gdb/callback.h"
+ #include "gdb/remote-sim.h"
+ #include "gdb/signals.h"
+ #include "gdb/sim-m32c.h"
+
+ #include "cpu.h"
+ #include "mem.h"
+ #include "load.h"
+ #include "syscalls.h"
+
+ /* I don't want to wrap up all the minisim's data structures in an
+ object and pass that around. That'd be a big change, and neither
+ GDB nor run needs that ability.
+
+ So we just have one instance, that lives in global variables, and
+ each time we open it, we re-initialize it. */
+ struct sim_state
+ {
+ const char *message;
+ };
+
+ static struct sim_state the_minisim = {
+ "This is the sole m32c minisim instance. See libsim.a's global variables."
+ };
+
+ static int open;
+
+ SIM_DESC
+ sim_open (SIM_OPEN_KIND kind,
+ struct host_callback_struct *callback,
+ struct bfd *abfd,
+ char **argv)
+ {
+ if (open)
+ fprintf (stderr, "m32c minisim: re-opened sim\n");
+
+ /* The 'run' interface doesn't use this function, so we don't care
+ about KIND; it's always SIM_OPEN_DEBUG. */
+ if (kind != SIM_OPEN_DEBUG)
+ fprintf (stderr, "m32c minisim: sim_open KIND != SIM_OPEN_DEBUG: %d\n",
+ kind);
+
+ if (abfd)
+ m32c_set_mach (bfd_get_mach (abfd));
+
+ /* We can use ABFD, if non-NULL to select the appropriate
+ architecture. But we only support the r8c right now. */
+
+ set_callbacks (callback);
+
+ /* We don't expect any command-line arguments. */
+
+ init_mem ();
+ init_regs ();
+
+ open = 1;
+ return &the_minisim;
+ }
+
+ static void
+ check_desc (SIM_DESC sd)
+ {
+ if (sd != &the_minisim)
+ fprintf (stderr, "m32c minisim: desc != &the_minisim\n");
+ }
+
+ void
+ sim_close (SIM_DESC sd, int quitting)
+ {
+ check_desc (sd);
+
+ /* Not much to do. At least free up our memory. */
+ init_mem ();
+
+ open = 0;
+ }
+
+ static bfd *
+ open_objfile (const char *filename)
+ {
+ bfd *prog = bfd_openr (filename, 0);
+
+ if (! prog)
+ {
+ fprintf (stderr, "Can't read %s\n", filename);
+ return 0;
+ }
+
+ if (! bfd_check_format (prog, bfd_object))
+ {
+ fprintf (stderr, "%s not a m32c program\n", filename);
+ return 0;
+ }
+
+ return prog;
+ }
+
+
+ SIM_RC
+ sim_load (SIM_DESC sd, char *prog, struct bfd *abfd, int from_tty)
+ {
+ check_desc (sd);
+
+ if (! abfd)
+ abfd = open_objfile (prog);
+ if (! abfd)
+ return SIM_RC_FAIL;
+
+ m32c_load (abfd);
+
+ return SIM_RC_OK;
+ }
+
+ SIM_RC
+ sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
+ {
+ check_desc (sd);
+
+ if (abfd)
+ m32c_load (abfd);
+
+ return SIM_RC_OK;
+ }
+
+ int
+ sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
+ {
+ check_desc (sd);
+
+ if (mem == 0)
+ return 0;
+
+ mem_get_blk ((int) mem, buf, length);
+
+ return length;
+ }
+
+ int
+ sim_write (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
+ {
+ check_desc (sd);
+
+ mem_put_blk ((int) mem, buf, length);
+
+ return length;
+ }
+
+
+ /* Read the LENGTH bytes at BUF as an little-endian value. */
+ static DI
+ get_le (unsigned char *buf, int length)
+ {
+ DI acc = 0;
+ while (--length >= 0)
+ acc = (acc << 8) + buf[length];
+
+ return acc;
+ }
+
+ /* Store VAL as a little-endian value in the LENGTH bytes at BUF. */
+ static void
+ put_le (unsigned char *buf, int length, DI val)
+ {
+ int i;
+
+ for (i = 0; i < length; i++)
+ {
+ buf[i] = val & 0xff;
+ val >>= 8;
+ }
+ }
+
+ static int
+ check_regno (enum m32c_sim_reg regno)
+ {
+ return 0 <= regno && regno < m32c_sim_reg_num_regs;
+ }
+
+ static size_t
+ mask_size (int addr_mask)
+ {
+ switch (addr_mask)
+ {
+ case 0xffff:
+ return 2;
+ case 0xfffff:
+ case 0xffffff:
+ return 3;
+ default:
+ fprintf (stderr,
+ "m32c minisim: addr_mask_size: unexpected mask 0x%x\n",
+ addr_mask);
+ return sizeof (addr_mask);
+ }
+ }
+
+ static size_t
+ reg_size (enum m32c_sim_reg regno)
+ {
+ switch (regno)
+ {
+ case m32c_sim_reg_r0_bank0:
+ case m32c_sim_reg_r1_bank0:
+ case m32c_sim_reg_r2_bank0:
+ case m32c_sim_reg_r3_bank0:
+ case m32c_sim_reg_r0_bank1:
+ case m32c_sim_reg_r1_bank1:
+ case m32c_sim_reg_r2_bank1:
+ case m32c_sim_reg_r3_bank1:
+ case m32c_sim_reg_flg:
+ case m32c_sim_reg_svf:
+ return 2;
+
+ case m32c_sim_reg_a0_bank0:
+ case m32c_sim_reg_a1_bank0:
+ case m32c_sim_reg_fb_bank0:
+ case m32c_sim_reg_sb_bank0:
+ case m32c_sim_reg_a0_bank1:
+ case m32c_sim_reg_a1_bank1:
+ case m32c_sim_reg_fb_bank1:
+ case m32c_sim_reg_sb_bank1:
+ case m32c_sim_reg_usp:
+ case m32c_sim_reg_isp:
+ return mask_size (addr_mask);
+
+ case m32c_sim_reg_pc:
+ case m32c_sim_reg_intb:
+ case m32c_sim_reg_svp:
+ case m32c_sim_reg_vct:
+ return mask_size (membus_mask);
+
+ case m32c_sim_reg_dmd0:
+ case m32c_sim_reg_dmd1:
+ return 1;
+
+ case m32c_sim_reg_dct0:
+ case m32c_sim_reg_dct1:
+ case m32c_sim_reg_drc0:
+ case m32c_sim_reg_drc1:
+ return 2;
+
+ case m32c_sim_reg_dma0:
+ case m32c_sim_reg_dma1:
+ case m32c_sim_reg_dsa0:
+ case m32c_sim_reg_dsa1:
+ case m32c_sim_reg_dra0:
+ case m32c_sim_reg_dra1:
+ return 3;
+
+ default:
+ fprintf (stderr, "m32c minisim: unrecognized register number: %d\n",
+ regno);
+ return -1;
+ }
+ }
+
+ int
+ sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
+ {
+ size_t size;
+
+ check_desc (sd);
+
+ if (! check_regno (regno))
+ return 0;
+
+ size = reg_size (regno);
+ if (length == size)
+ {
+ DI val;
+
+ switch (regno)
+ {
+ case m32c_sim_reg_r0_bank0: val = regs.r[0].r_r0; break;
+ case m32c_sim_reg_r1_bank0: val = regs.r[0].r_r1; break;
+ case m32c_sim_reg_r2_bank0: val = regs.r[0].r_r2; break;
+ case m32c_sim_reg_r3_bank0: val = regs.r[0].r_r3; break;
+ case m32c_sim_reg_a0_bank0: val = regs.r[0].r_a0; break;
+ case m32c_sim_reg_a1_bank0: val = regs.r[0].r_a1; break;
+ case m32c_sim_reg_fb_bank0: val = regs.r[0].r_fb; break;
+ case m32c_sim_reg_sb_bank0: val = regs.r[0].r_sb; break;
+ case m32c_sim_reg_r0_bank1: val = regs.r[1].r_r0; break;
+ case m32c_sim_reg_r1_bank1: val = regs.r[1].r_r1; break;
+ case m32c_sim_reg_r2_bank1: val = regs.r[1].r_r2; break;
+ case m32c_sim_reg_r3_bank1: val = regs.r[1].r_r3; break;
+ case m32c_sim_reg_a0_bank1: val = regs.r[1].r_a0; break;
+ case m32c_sim_reg_a1_bank1: val = regs.r[1].r_a1; break;
+ case m32c_sim_reg_fb_bank1: val = regs.r[1].r_fb; break;
+ case m32c_sim_reg_sb_bank1: val = regs.r[1].r_sb; break;
+
+ case m32c_sim_reg_usp: val = regs.r_usp; break;
+ case m32c_sim_reg_isp: val = regs.r_isp; break;
+ case m32c_sim_reg_pc: val = regs.r_pc; break;
+ case m32c_sim_reg_intb:
+ val = regs.r_intbl * 65536 + regs.r_intbl; break;
+ case m32c_sim_reg_flg: val = regs.r_flags; break;
+
+ /* These registers aren't implemented by the minisim. */
+ case m32c_sim_reg_svf:
+ case m32c_sim_reg_svp:
+ case m32c_sim_reg_vct:
+ case m32c_sim_reg_dmd0:
+ case m32c_sim_reg_dmd1:
+ case m32c_sim_reg_dct0:
+ case m32c_sim_reg_dct1:
+ case m32c_sim_reg_drc0:
+ case m32c_sim_reg_drc1:
+ case m32c_sim_reg_dma0:
+ case m32c_sim_reg_dma1:
+ case m32c_sim_reg_dsa0:
+ case m32c_sim_reg_dsa1:
+ case m32c_sim_reg_dra0:
+ case m32c_sim_reg_dra1:
+ return 0;
+
+ default:
+ fprintf (stderr, "m32c minisim: unrecognized register number: %d\n",
+ regno);
+ return -1;
+ }
+
+ put_le (buf, length, val);
+ }
+
+ return size;
+ }
+
+ int
+ sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
+ {
+ size_t size;
+
+ check_desc (sd);
+
+ if (! check_regno (regno))
+ return 0;
+
+ size = reg_size (regno);
+
+ if (length == size)
+ {
+ DI val = get_le (buf, length);
+
+ switch (regno)
+ {
+ case m32c_sim_reg_r0_bank0: regs.r[0].r_r0 = val & 0xffff; break;
+ case m32c_sim_reg_r1_bank0: regs.r[0].r_r1 = val & 0xffff; break;
+ case m32c_sim_reg_r2_bank0: regs.r[0].r_r2 = val & 0xffff; break;
+ case m32c_sim_reg_r3_bank0: regs.r[0].r_r3 = val & 0xffff; break;
+ case m32c_sim_reg_a0_bank0: regs.r[0].r_a0 = val & addr_mask; break;
+ case m32c_sim_reg_a1_bank0: regs.r[0].r_a1 = val & addr_mask; break;
+ case m32c_sim_reg_fb_bank0: regs.r[0].r_fb = val & addr_mask; break;
+ case m32c_sim_reg_sb_bank0: regs.r[0].r_sb = val & addr_mask; break;
+ case m32c_sim_reg_r0_bank1: regs.r[1].r_r0 = val & 0xffff; break;
+ case m32c_sim_reg_r1_bank1: regs.r[1].r_r1 = val & 0xffff; break;
+ case m32c_sim_reg_r2_bank1: regs.r[1].r_r2 = val & 0xffff; break;
+ case m32c_sim_reg_r3_bank1: regs.r[1].r_r3 = val & 0xffff; break;
+ case m32c_sim_reg_a0_bank1: regs.r[1].r_a0 = val & addr_mask; break;
+ case m32c_sim_reg_a1_bank1: regs.r[1].r_a1 = val & addr_mask; break;
+ case m32c_sim_reg_fb_bank1: regs.r[1].r_fb = val & addr_mask; break;
+ case m32c_sim_reg_sb_bank1: regs.r[1].r_sb = val & addr_mask; break;
+
+ case m32c_sim_reg_usp: regs.r_usp = val & addr_mask; break;
+ case m32c_sim_reg_isp: regs.r_isp = val & addr_mask; break;
+ case m32c_sim_reg_pc: regs.r_pc = val & membus_mask; break;
+ case m32c_sim_reg_intb:
+ regs.r_intbl = (val & membus_mask) & 0xffff;
+ regs.r_intbh = (val & membus_mask) >> 16;
+ break;
+ case m32c_sim_reg_flg: regs.r_flags = val & 0xffff; break;
+
+ /* These registers aren't implemented by the minisim. */
+ case m32c_sim_reg_svf:
+ case m32c_sim_reg_svp:
+ case m32c_sim_reg_vct:
+ case m32c_sim_reg_dmd0:
+ case m32c_sim_reg_dmd1:
+ case m32c_sim_reg_dct0:
+ case m32c_sim_reg_dct1:
+ case m32c_sim_reg_drc0:
+ case m32c_sim_reg_drc1:
+ case m32c_sim_reg_dma0:
+ case m32c_sim_reg_dma1:
+ case m32c_sim_reg_dsa0:
+ case m32c_sim_reg_dsa1:
+ case m32c_sim_reg_dra0:
+ case m32c_sim_reg_dra1:
+ return 0;
+
+ default:
+ fprintf (stderr, "m32c minisim: unrecognized register number: %d\n",
+ regno);
+ return -1;
+ }
+ }
+
+ return size;
+ }
+
+ void
+ sim_info (SIM_DESC sd, int verbose)
+ {
+ check_desc (sd);
+
+ printf ("The m32c minisim doesn't collect any statistics.\n");
+ }
+
+ static volatile int stop;
+ static enum sim_stop reason;
+ int siggnal;
+
+
+ /* Given a signal number used by the M32C bsp (that is, newlib),
+ return a host signal number. (Oddly, the gdb/sim interface uses
+ host signal numbers...) */
+ int
+ m32c_signal_to_host (int m32c)
+ {
+ switch (m32c)
+ {
+ case 4:
+ #ifdef SIGILL
+ return SIGILL;
+ #else
+ return SIGSEGV;
+ #endif
+
+ case 5:
+ return SIGTRAP;
+
+ case 10:
+ #ifdef SIGBUS
+ return SIGBUS;
+ #else
+ return SIGSEGV;
+ #endif
+
+ case 11:
+ return SIGSEGV;
+
+ case 24:
+ #ifdef SIGXCPU
+ return SIGXCPU;
+ #else
+ break;
+ #endif
+
+ case 2:
+ return SIGINT;
+
+ case 8:
+ #ifdef SIGFPE
+ return SIGFPE;
+ #else
+ break;
+ #endif
+
+ case 6:
+ return SIGABRT;
+ }
+
+ return 0;
+ }
+
+
+ /* Take a step return code RC and set up the variables consulted by
+ sim_stop_reason appropriately. */
+ void
+ handle_step (int rc)
+ {
+ if (M32C_STEPPED (rc)
+ || M32C_HIT_BREAK (rc))
+ {
+ reason = sim_stopped;
+ siggnal = TARGET_SIGNAL_TRAP;
+ }
+ else if (M32C_STOPPED (rc))
+ {
+ reason = sim_stopped;
+ siggnal = m32c_signal_to_host (M32C_STOP_SIG (rc));
+ }
+ else
+ {
+ assert (M32C_EXITED (rc));
+ reason = sim_exited;
+ siggnal = M32C_EXIT_STATUS (rc);
+ }
+ }
+
+
+ void
+ sim_resume (SIM_DESC sd, int step, int sig_to_deliver)
+ {
+ check_desc (sd);
+
+ if (sig_to_deliver != 0)
+ {
+ fprintf (stderr,
+ "Warning: the m32c minisim does not implement "
+ "signal delivery yet.\n"
+ "Resuming with no signal.\n");
+ }
+
+ if (step)
+ handle_step (decode_opcode ());
+ else
+ {
+ /* We don't clear 'stop' here, because then we would miss
+ interrupts that arrived on the way here. Instead, we clear
+ the flag in sim_stop_reason, after GDB has disabled the
+ interrupt signal handler. */
+ for (;;)
+ {
+ if (stop)
+ {
+ stop = 0;
+ reason = sim_stopped;
+ siggnal = TARGET_SIGNAL_INT;
+ break;
+ }
+
+ int rc = decode_opcode ();
+
+ if (! M32C_STEPPED (rc))
+ {
+ handle_step (rc);
+ break;
+ }
+ }
+ }
+ }
+
+ int
+ sim_stop (SIM_DESC sd)
+ {
+ stop = 1;
+
+ return 1;
+ }
+
+ void
+ sim_stop_reason (SIM_DESC sd, enum sim_stop *reason_p, int *sigrc_p)
+ {
+ check_desc (sd);
+
+ *reason_p = reason;
+ *sigrc_p = siggnal;
+ }
+
+ void
+ sim_do_command (SIM_DESC sd, char *cmd)
+ {
+ check_desc (sd);
+
+ char *p = cmd;
+
+ /* Skip leading whitespace. */
+ while (isspace (*p))
+ p++;
+
+ /* Find the extent of the command word. */
+ for (p = cmd; *p; p++)
+ if (isspace (*p))
+ break;
+
+ /* Null-terminate the command word, and record the start of any
+ further arguments. */
+ char *args;
+ if (*p)
+ {
+ *p = '\0';
+ args = p + 1;
+ while (isspace (*args))
+ args++;
+ }
+ else
+ args = p;
+
+ if (strcmp (cmd, "trace") == 0)
+ {
+ if (strcmp (args, "on") == 0)
+ trace = 1;
+ else if (strcmp (args, "off") == 0)
+ trace = 0;
+ else
+ printf ("The 'sim trace' command expects 'on' or 'off' "
+ "as an argument.\n");
+ }
+ else if (strcmp (cmd, "verbose") == 0)
+ {
+ if (strcmp (args, "on") == 0)
+ verbose = 1;
+ else if (strcmp (args, "off") == 0)
+ verbose = 0;
+ else
+ printf ("The 'sim verbose' command expects 'on' or 'off'"
+ " as an argument.\n");
+ }
+ else
+ printf ("The 'sim' command expects either 'trace' or 'verbose'"
+ " as a subcommand.\n");
+ }
Index: sim/m32c/gloss.S
===================================================================
RCS file: sim/m32c/gloss.S
diff -N sim/m32c/gloss.S
*** sim/m32c/gloss.S 1 Jan 1970 00:00:00 -0000
--- sim/m32c/gloss.S 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,11 ----
+ .global _exit
+ _exit:
+ mov.b #1,r0l
+ ste.b r0l,0xe0000
+ rts
+
+ .global _foo
+ _foo:
+ mov.b #2,r0l
+ ste.b r0l,0xe0000
+ rts
Index: sim/m32c/int.c
===================================================================
RCS file: sim/m32c/int.c
diff -N sim/m32c/int.c
*** sim/m32c/int.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/int.c 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,36 ----
+ #include "int.h"
+ #include "cpu.h"
+ #include "mem.h"
+
+ void
+ trigger_fixed_interrupt (int addr)
+ {
+ int s = get_reg (sp);
+ int f = get_reg (flags);
+ int p = get_reg (pc);
+
+ if (A16)
+ {
+ s -= 4;
+ put_reg (sp, s);
+ mem_put_hi (s, p);
+ mem_put_qi (s+2, f);
+ mem_put_qi (s+3, ((f >> 4) & 0x0f) | (p >> 16));
+ } else {
+ s -= 6;
+ put_reg (sp, s);
+ mem_put_si (s, p);
+ mem_put_hi (s+4, f);
+ }
+ put_reg (pc, mem_get_psi (addr));
+ set_flags (FLAGBIT_U | FLAGBIT_I | FLAGBIT_D, 0);
+ }
+
+ void
+ trigger_based_interrupt (int vector)
+ {
+ int addr = get_reg (intb) + vector * 4;
+ if (vector <= 31)
+ set_flags (FLAGBIT_U, 0);
+ trigger_fixed_interrupt (addr);
+ }
Index: sim/m32c/int.h
===================================================================
RCS file: sim/m32c/int.h
diff -N sim/m32c/int.h
*** sim/m32c/int.h 1 Jan 1970 00:00:00 -0000
--- sim/m32c/int.h 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,2 ----
+ extern void trigger_fixed_interrupt (int addr);
+ extern void trigger_based_interrupt (int vector);
Index: sim/m32c/load.c
===================================================================
RCS file: sim/m32c/load.c
diff -N sim/m32c/load.c
*** sim/m32c/load.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/load.c 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,107 ----
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+
+ #include "bfd.h"
+
+ #include "cpu.h"
+ #include "mem.h"
+
+ int (*decode_opcode)() = 0;
+ int default_machine = 0;
+
+ void
+ m32c_set_mach (unsigned long mach)
+ {
+ switch (mach)
+ {
+ case bfd_mach_m16c:
+ m32c_set_cpu (CPU_M16C);
+ if (verbose)
+ fprintf (stderr, "[cpu: r8c/m16c]\n");
+ break;
+ case bfd_mach_m32c:
+ m32c_set_cpu (CPU_M32C);
+ if (verbose)
+ fprintf (stderr, "[cpu: m32cm/m32c]\n");
+ break;
+ default:
+ fprintf (stderr, "unknown m32c machine type 0x%lx\n", mach);
+ decode_opcode = 0;
+ break;
+ }
+ }
+
+ void
+ m32c_load (bfd *prog)
+ {
+ asection *s;
+ unsigned long mach = bfd_get_mach (prog);
+ unsigned long highest_addr_loaded = 0;
+
+ if (mach == 0 && default_machine != 0)
+ mach = default_machine;
+
+ m32c_set_mach (mach);
+
+ for (s = prog->sections; s; s = s->next)
+ {
+ #if 0
+ /* This was a good idea until we started storing the RAM data in
+ ROM, at which point everything was all messed up. The code
+ remains as a reminder. */
+ if ((s->flags & SEC_ALLOC) && !(s->flags & SEC_READONLY))
+ {
+ if (strcmp (bfd_get_section_name (prog, s), ".stack"))
+ {
+ int secend = bfd_get_section_size (s) + bfd_section_lma (prog, s);
+ if (heaptop < secend && bfd_section_lma (prog, s) < 0x10000)
+ {
+ heaptop = heapbottom = secend;
+ }
+ }
+ }
+ #endif
+ if (s->flags & SEC_LOAD)
+ {
+ char *buf;
+ bfd_size_type size;
+
+ size = bfd_get_section_size (s);
+ if (size <= 0)
+ continue;
+
+ bfd_vma base = bfd_section_lma (prog, s);
+ if (verbose)
+ fprintf(stderr, "[load a=%08x s=%08x %s]\n",
+ (int)base, (int)size, bfd_get_section_name (prog, s));
+ buf = (char *) malloc (size);
+ bfd_get_section_contents (prog, s, buf, 0, size);
+ mem_put_blk (base, buf, size);
+ free (buf);
+ if (highest_addr_loaded < base + size - 1 && size >= 4)
+ highest_addr_loaded = base + size - 1;
+ }
+ }
+
+ if (strcmp (bfd_get_target (prog), "srec") == 0)
+ {
+ heaptop = heapbottom = 0;
+ switch (mach)
+ {
+ case bfd_mach_m16c:
+ if (highest_addr_loaded > 0x10000)
+ regs.r_pc = mem_get_si (0x000ffffc) & membus_mask;
+ else
+ regs.r_pc = mem_get_si (0x000fffc) & membus_mask;
+ break;
+ case bfd_mach_m32c:
+ regs.r_pc = mem_get_si (0x00fffffc) & membus_mask;
+ break;
+ }
+ }
+ else
+ regs.r_pc = prog->start_address;
+ if (verbose)
+ fprintf(stderr, "[start pc=%08x]\n", (unsigned int)regs.r_pc);
+ }
Index: sim/m32c/load.h
===================================================================
RCS file: sim/m32c/load.h
diff -N sim/m32c/load.h
*** sim/m32c/load.h 1 Jan 1970 00:00:00 -0000
--- sim/m32c/load.h 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,6 ----
+ #include "bfd.h"
+
+ extern int default_machine;
+
+ void m32c_set_mach (int mach);
+ void m32c_load (bfd *);
Index: sim/m32c/m32c.opc
===================================================================
RCS file: sim/m32c/m32c.opc
diff -N sim/m32c/m32c.opc
*** sim/m32c/m32c.opc 1 Jan 1970 00:00:00 -0000
--- sim/m32c/m32c.opc 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,2072 ----
+ #include <stdio.h> /* -*- mode: c -*- */
+ #include <stdlib.h>
+
+ #include "cpu.h"
+ #include "mem.h"
+ #include "misc.h"
+ #include "int.h"
+
+ #define AU __attribute__((unused))
+
+ #define tprintf if (trace) printf
+
+ static unsigned char
+ getbyte ()
+ {
+ int tsave = trace;
+ unsigned char b;
+
+ if (trace == 1)
+ trace = 0;
+ b = mem_get_pc ();
+ regs.r_pc ++;
+ trace = tsave;
+ return b;
+ }
+
+ #define M32C_ONLY() /* FIXME: add something here */
+
+ #define GETBYTE() (op[opi++] = getbyte())
+
+ #define UNSUPPORTED() unsupported("unsupported", orig_pc)
+ #define NOTYET() unsupported("unimplemented", orig_pc)
+
+ static void
+ unsupported (char *tag, int orig_pc)
+ {
+ int i;
+ printf("%s opcode at %08x\n", tag, orig_pc);
+ regs.r_pc = orig_pc;
+ for (i=0; i<2; i++)
+ {
+ int b = mem_get_pc();
+ printf(" %s", bits(b>>4, 4));
+ printf(" %s", bits(b, 4));
+ regs.r_pc ++;
+ }
+ printf("\n");
+ regs.r_pc = orig_pc;
+ for (i=0; i<6; i++)
+ {
+ printf(" %02x", mem_get_pc ());
+ regs.r_pc ++;
+ }
+ printf("\n");
+ exit(1);
+ }
+
+ static int
+ IMM(int bytes)
+ {
+ int rv = 0;
+ switch (bytes)
+ {
+ case 1:
+ rv = mem_get_qi (get_reg(pc));
+ break;
+ case 2:
+ rv = mem_get_hi (get_reg(pc));
+ break;
+ case 3:
+ rv = mem_get_psi (get_reg(pc));
+ break;
+ case 4:
+ rv = mem_get_si (get_reg(pc));
+ break;
+ }
+ regs.r_pc += bytes;
+ return rv;
+ }
+
+ #define IMM4() (immm >= 8 ? 7 - immm : immm + 1)
+
+ #define NO_PREFIX() PREFIX(0,0,0)
+
+ void
+ prefix (src_allowed, dest_allowed, index_bytewidth)
+ {
+ }
+
+ #define MATH_OP(dc,s,c,op) \
+ { \
+ int ma, mb; \
+ ma = get_src(dc); \
+ mb = s & b2mask[dc.bytes]; \
+ ll = (long long)ma op (long long)mb op c; \
+ tprintf("0x%x " #op " 0x%x " #op " 0x%x = 0x%llx\n", ma, mb, c, ll); \
+ ma = sign_ext (ma, dc.bytes * 8); \
+ mb = sign_ext (s, dc.bytes * 8); \
+ v = ma op mb op c; \
+ tprintf("%d " #op " %d " #op " %d = %d\n", ma, mb, c, v); \
+ set_oszc (v, dc.bytes, ll > ((1 op 1) ? b2mask[dc.bytes] : 0)); \
+ put_dest (dc, v); \
+ }
+
+ #define LOGIC_OP(dc,s,op) \
+ { \
+ int ma, mb; \
+ ma = get_src(dc); \
+ mb = s & b2mask[dc.bytes]; \
+ v = ma op mb; \
+ tprintf("0x%x " #op " 0x%x = 0x%x\n", ma, mb, v); \
+ set_sz (v, dc.bytes); \
+ put_dest (dc, v); \
+ }
+
+ #define BIT_OP(dc,bit,expr) \
+ b = get_bit2 (dc, bitindex == -1 ? bit : bitindex); \
+ v = expr; \
+ tprintf ("b=%d, bit=%d, carry=%d, %s = %d\n", b, bitindex == -1 ? bit : bitindex, carry, #expr, v); \
+ put_bit2 (dc, bitindex == -1 ? bit : bitindex, v);
+
+ #define BIT_OPC(dc,bit,expr) \
+ b = get_bit2 (dc, bitindex == -1 ? bit : bitindex); \
+ v = expr; \
+ tprintf ("b=%d, bit=%d, carry=%d, %s = %d\n", b, bitindex == -1 ? bit : bitindex, carry, #expr, v); \
+ set_c (v);
+
+ #define carry (FLAG_C ? 1 : 0)
+
+ static void
+ cmp (int d, int s, int bytes)
+ {
+ int a, b, f=0;
+ a = d - s;
+ b = sign_ext (d, bytes*8) - sign_ext (s, bytes*8);
+ tprintf ("cmp: %x - %x = %08x, %x - %x = %d\n",
+ d, s, a,
+ sign_ext(d,bytes*8), sign_ext(s,bytes*8), b);
+
+ if (b == 0)
+ f |= FLAGBIT_Z;
+ if (b & b2signbit[bytes])
+ f |= FLAGBIT_S;
+ if ((d & b2mask[bytes]) >= (s & b2mask[bytes]))
+ f |= FLAGBIT_C;
+ if (b < b2minsigned[bytes] || b > b2maxsigned[bytes])
+ f |= FLAGBIT_O;
+
+ set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f);
+ }
+
+ static void
+ dadd_op (int ddd, int dd, int sss, int ss, int imm, int add, int cy, int w)
+ {
+ srcdest sc, dc;
+ int a, b=0, res;
+
+ prefix (0, 0, 0);
+
+ if (!imm)
+ {
+ sc = decode_src23 (sss, ss, w+1);
+ b = get_src (sc);
+ }
+ dc = decode_dest23 (ddd, dd, w+1);
+ a = get_src (dc);
+ if (imm)
+ b = IMM(w+1);
+
+ a = bcd2int(a, w);
+ b = bcd2int(b, w);
+
+ tprintf("decimal: %d %s %d", a, add?"+":"-", b);
+ if (cy)
+ tprintf(" c=%d", carry);
+
+ if (add)
+ {
+ res = a + b;
+ if (cy)
+ res += carry;
+ cy = res > (w ? 9999 : 99);
+ }
+ else
+ {
+ res = a - b;
+ if (cy)
+ res -= (1-carry);
+ cy = res >= 0;
+ if (res < 0)
+ res += w ? 10000 : 100;
+ }
+
+ res = int2bcd (res, w);
+ tprintf(" = %x\n", res);
+
+ set_szc (res, w+1, cy);
+
+ put_dest (dc, res);
+ }
+ #define DADDV(A,C) dadd_op(ddd, dd, sss, ss, 0, A, C, w)
+ #define DADDI(A,C) dadd_op(ddd, dd, 0, 0, 1, A, C, w)
+
+ static void
+ div_op (int sss, int ss, int u, int x, int bytes)
+ {
+ srcdest sc;
+ int s, v, a, b;
+
+ if (sss == -1)
+ s = IMM(bytes);
+ else
+ {
+ sc = decode_dest23 (sss, ss, bytes);
+ s = get_src (sc);
+ }
+
+ v = get_reg (bytes > 1 ? r2r0 : r0);
+
+ if (!u)
+ {
+ /* FIXME? do we sign extend a0/a1 to .L? Docs say zero extend. */
+ s = sign_ext (s, bytes*8);
+ v = sign_ext (v, bytes*8);
+ }
+
+ if (s == 0)
+ {
+ set_flags (FLAGBIT_O, FLAGBIT_O);
+ return;
+ }
+
+ if (u)
+ {
+ a = (unsigned int)v / (unsigned int)s;
+ b = (unsigned int)v % (unsigned int)s;
+ }
+ else
+ {
+ a = v / s;
+ b = v % s;
+ }
+ if (x)
+ {
+ if ((s > 0 && b < 0)
+ || (s < 0 && b > 0))
+ {
+ a --;
+ b += s;
+ }
+ }
+ tprintf ("%d / %d = %d rem %d\n", v, s, a, b);
+ if ((!u && (a > b2maxsigned[bytes]
+ || a < b2minsigned[bytes]))
+ || (u && (a > b2mask[bytes])))
+ set_flags (FLAGBIT_O, FLAGBIT_O);
+ else
+ set_flags (FLAGBIT_O, 0);
+
+ switch (bytes)
+ {
+ case 1:
+ put_reg (r0l, a);
+ put_reg (r0h, b);
+ break;
+ case 2:
+ put_reg (r0, a);
+ put_reg (r2, b);
+ break;
+ case 4:
+ put_reg (r2r0, a);
+ break;
+ }
+ }
+
+ static void
+ index_op (int sss, int ss, int do_s, int do_d, int scale, int w)
+ {
+ srcdest sc = decode_src23 (sss, ss, w+1);
+ int v = get_src (sc) * scale;
+ tprintf("%d = %d * %d, %d %d\n", v, get_src(sc), scale, do_s, do_d);
+ decode_index (do_s * v, do_d * v);
+ }
+ #define INDEXOP(scale,do_s,do_d) index_op (sss, ss, do_s, do_d, scale, w); goto next_opcode
+
+ static void
+ rot_op (srcdest sd, int rotc, int count)
+ {
+ int mask = (sd.bytes == 2) ? 0xffff : 0xff;
+ int msb = (sd.bytes == 2) ? 0x8000 : 0x80;
+ int v = get_src (sd);
+ int c = carry, ct;
+
+ tprintf("%s %x by %d\n", rotc ? "rotc" : "rot", v, count);
+ tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
+ while (count > 0)
+ {
+ ct = (v & msb) ? 1 : 0;
+ v <<= 1;
+ v |= rotc ? c : ct;
+ v &= mask;
+ c = ct;
+ tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
+ count --;
+ }
+ while (count < 0)
+ {
+ ct = v & 1;
+ v >>= 1;
+ v |= (rotc ? c : ct) * msb;
+ c = ct;
+ tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
+ count ++;
+ }
+ put_dest (sd, v);
+ set_szc (v, sd.bytes, c);
+ }
+
+ static void
+ shift_op (srcdest sd, int arith, int count, int setc)
+ {
+ int mask = (sd.bytes == 2) ? 0xffff : 0xff;
+ int msb = (sd.bytes == 2) ? 0x8000 : 0x80;
+ int v = get_src (sd);
+ int c = 0;
+ int o = 0;
+
+ if (sd.bytes == 4)
+ {
+ mask = 0xffffffffU;
+ msb = 0x80000000U;
+ }
+
+ tprintf("%s %x by %d\n", arith ? "sha" : "shl", v, count);
+ tprintf (": %s %d %d\n", bits(v, 8*sd.bytes), c, o);
+ while (count > 0)
+ {
+ c = (v & msb) ? 1 : 0;
+ v <<= 1;
+ v &= mask;
+ if (c != ((v & msb) ? 1 : 0))
+ o = 1;
+ tprintf (": %s %d %d\n", bits(v, 8*sd.bytes), c, o);
+ count --;
+ }
+ while (count < 0)
+ {
+ c = v & 1;
+ if (arith)
+ v = (v & msb) | (v >> 1);
+ else
+ v = (v >> 1) & (msb - 1);
+ tprintf (": %s %d %d\n", bits(v, 8*sd.bytes), c, o);
+ count ++;
+ }
+ put_dest (sd, v);
+ set_sz (v, sd.bytes);
+ if (setc)
+ set_c (c);
+ set_flags (FLAGBIT_O, o ? FLAGBIT_O : 0);
+ }
+
+ int
+ decode_m32c()
+ {
+ unsigned char op[40];
+ int opi;
+ int orig_pc;
+ int v, a, b;
+ long long ll;
+ srcdest sc, dc;
+ int imm;
+ int bitindex = -1;
+ int t0, t1=0, t2, t3=0;
+ int ta0, ta1, dif;
+
+ step_result = M32C_MAKE_STEPPED ();
+
+ decode_indirect (0, 0);
+ decode_index (0, 0);
+
+ next_opcode:
+ opi = 0;
+ orig_pc = get_reg (pc);
+
+ tprintf("trace: decode pc = %06x\n", orig_pc);
+
+ /* VARY sss 000 001 010 011 100 */
+ /* VARY ddd 000 001 010 011 100 */
+
+ /* 0000 1001 indirect dest */
+
+ decode_indirect (0, 1);
+ goto next_opcode;
+
+ /* 0100 0001 indirect src */
+
+ decode_indirect (1, 0);
+ goto next_opcode;
+
+ /* 0100 1001 indirect src and dest */
+
+ decode_indirect (1, 1);
+ goto next_opcode;
+
+ /* 1010 ddd w dd01 1111 ABS.size dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ v = sign_ext (get_src (dc), w?16:8);
+ a = v<0 ? -v : v;
+ tprintf("abs(%d) = %d\n", v, a);
+ set_osz(a, w+1);
+ put_dest (dc, a);
+
+ /* 0000 0001 1000 ddd w dd10 1110 ADC.size #IMM,dest */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ imm = IMM (w+1);
+ MATH_OP (dc, imm, carry, +);
+
+ /* 0000 0001 1sss ddd w dd ss 0100 ADC.size src,dest */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, w+1);
+ dc = decode_dest23 (ddd, dd, w+1);
+ b = get_src (sc);
+ MATH_OP (dc, b, carry, +);
+
+ /* 1011 ddd w dd01 1110 ADCF.size dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ MATH_OP (dc, 0, carry, +);
+
+ /* 1000 ddd w dd10 1110 ADD.size:G #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23(ddd, dd, w+1);
+ imm = IMM(w+1);
+ MATH_OP (dc, imm, 0, +);
+
+ /* 1000 ddd0 dd11 0001 ADD.L:G #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23(ddd, dd, 4);
+ imm = IMM(4);
+ MATH_OP (dc, imm, 0, +);
+
+ /* 111L ddd w dd11 immm ADD.size:Q #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23(ddd, dd, L ? 4 : (w+1));
+ imm = sign_ext (immm, 4);
+ MATH_OP (dc, imm, 0, +);
+
+ /* 00dd 011w ADD.size:S #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest2(dd, w+1);
+ imm = IMM (w+1);
+ MATH_OP (dc, imm, 0, +);
+
+ /* 10i0 110d ADD.L:S #IMM,A0/A1 */
+
+ prefix (0, 0, 0);
+ dc = reg_sd (d ? a1 : a0);
+ imm = i ? 2 : 1;
+ MATH_OP (dc, imm, 0, +);
+
+ /* 1sss ddd w dd ss 1000 ADD.size:G src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23(sss, ss, w+1);
+ dc = decode_dest23(ddd, dd, w+1);
+ b = get_src (sc);
+ MATH_OP (dc, b, 0, +);
+
+ /* 1sss ddd1 dd ss 0010 ADD.L:G src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23(sss, ss, 4);
+ dc = decode_dest23(ddd, dd, 4);
+ b = get_src (sc);
+ MATH_OP (dc, b, 0, +);
+
+ /* 1011 0110 0001 0011 ADD.L:G #IMM16,SP */
+
+ prefix (0, 0, 0);
+ dc = reg_sd (sp);
+ b = sign_ext (IMM(2), 16);
+ MATH_OP (dc, b, 0, +);
+
+ /* 01ii 001i ADD.L:Q #IMM3,SP */
+
+ prefix (0, 0, 0);
+ dc = reg_sd (sp);
+ b = ii * 2 + i + 1;
+ MATH_OP (dc, b, 0, +);
+
+ /* 1011 0110 0000 0011 ADD.L:S #IMM8,SP */
+
+ prefix (0, 0, 0);
+ dc = reg_sd (sp);
+ b = sign_ext (IMM(1), 8);
+ MATH_OP (dc, b, 0, +);
+
+ /* 1000 ddd0 dd01 0001 ADDX #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23(ddd, dd, 4);
+ imm = sign_ext (IMM(1), 8);
+ MATH_OP (dc, imm, 0, +);
+
+ /* 1sss ddd0 dd ss 0010 ADDX src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23(sss, ss, 1);
+ dc = decode_dest23(ddd, dd, 4);
+ b = sign_ext (get_src (sc), 8);
+ MATH_OP (dc, b, 0, +);
+
+ /* 1111 ddd w dd01 immm ADJNZ.size #IMM,dest,label */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ v = get_src (dc);
+ imm = sign_ext(immm, 4);
+ tprintf("%d + %d = %d\n", v, imm, v+imm);
+ v += imm;
+ put_dest (dc, v);
+ a = sign_ext (IMM(1), 8);
+ if ((v & (w ? 0xffff : 0xff)) != 0)
+ {
+ tprintf("jmp: %x + 2 + %d = ", get_reg (pc), a);
+ put_reg (pc, orig_pc + 2 + a);
+ tprintf("%x\n", get_reg (pc));
+ }
+
+ /* 1000 ddd w dd11 1111 AND.size:G #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23(ddd, dd, w+1);
+ imm = IMM(w+1);
+ LOGIC_OP (dc, imm, &);
+
+ /* 01dd 110w AND.size:S #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest2(dd, w+1);
+ imm = IMM (w+1);
+ LOGIC_OP (dc, imm, &);
+
+ /* 1sss ddd w dd ss 1101 AND.size:G src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23(sss, ss, w+1);
+ dc = decode_dest23(ddd, dd, w+1);
+ b = get_src (sc);
+ LOGIC_OP (dc, b, &);
+
+ /* 0000 0001 1101 sss0 ss00 1bit BAND src */
+
+ sc = decode_src23 (sss, ss, 1);
+ BIT_OPC (sc, bit, b & carry);
+
+ /* 1101 ddd0 dd11 0bit BCLR dest */
+
+ dc = decode_dest23 (ddd, dd, 1);
+ BIT_OP (dc, bit, 0);
+
+ /* 1100 ddd w dd10 1110 BITINDEX.size src */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ bitindex = get_src (dc);
+ tprintf ("bitindex set to %d\n", bitindex);
+ goto next_opcode;
+
+ /* 1101 ddd0 dd01 0bit BMcnd dest */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, 1);
+ if (condition_true (IMM (1)))
+ put_bit2 (dc, bit, 1);
+ else
+ put_bit2 (dc, bit, 0);
+
+ /* 1101 1001 0c10 1cnd BMcnd C */
+
+ prefix (0, 0, 0);
+ if (condition_true (c * 8 + cnd))
+ set_c (1);
+ else
+ set_c (0);
+
+ /* 0000 0001 1101 sss0 ss01 1bit BNAND src */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 1);
+ BIT_OPC (sc, bit, !b & carry);
+
+ /* 0000 0001 1101 sss0 ss11 0bit BNOR src */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 1);
+ BIT_OPC (sc, bit, !b | carry);
+
+ /* 1101 ddd0 dd01 1bit BNOT dest */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, 1);
+ BIT_OP (dc, bit, !b);
+
+ /* 0000 0001 1101 sss0 ss00 0bit BNTST src */
+
+ prefix (0, 0, 0);
+ sc = decode_dest23 (sss, ss, 1);
+ b = get_bit2 (sc, bit);
+ set_zc (!b, !b);
+
+ /* 0000 0001 1101 sss0 ss11 1bit BNXOR src */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 1);
+ BIT_OPC (sc, bit, !b ^ carry);
+
+ /* 0000 0001 1101 sss0 ss10 0bit BOR src */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 1);
+ BIT_OPC (sc, bit, b | carry);
+
+ /* 0000 0000 BRK */
+
+ /* We report the break to our caller with the PC still pointing at the
+ breakpoint instruction. */
+ put_reg (pc, orig_pc);
+ if (verbose)
+ printf("[break]\n");
+ return M32C_MAKE_HIT_BREAK ();
+
+ /* 0000 1000 BRK */
+
+ if (verbose)
+ printf("[break2]\n");
+ return M32C_MAKE_HIT_BREAK ();
+
+ /* 1101 ddd0 dd11 1bit BSET dest */
+
+ dc = decode_dest23 (ddd, dd, 1);
+ BIT_OP (dc, bit, 1);
+
+ /* 1101 sss0 ss00 0bit BTST:G src */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 1);
+ b = get_bit2 (sc, bit);
+ set_zc (!b, b);
+
+ /* 00bb 101b BTST:S src */
+
+ sc = decode_src23 (3, 3, 1); /* bit,base:19 */
+ b = get_bit2 (sc, bb*2 + b);
+ set_zc (!b, b);
+
+ /* 1101 ddd0 dd10 0bit BTSTC dest */
+
+ prefix (0, 0, 0);
+ sc = decode_dest23 (ddd, dd, 1);
+ b = get_bit2 (sc, bit);
+ set_zc (!b, b);
+ put_bit2 (sc, bit, 0);
+
+ /* 1101 ddd0 dd10 1bit BTSTS dest */
+
+ prefix (0, 0, 0);
+ sc = decode_dest23 (ddd, dd, 1);
+ b = get_bit2 (sc, bit);
+ set_zc (!b, b);
+ put_bit2 (sc, bit, 1);
+
+ /* 0000 0001 1101 sss0 ss10 1bit BXOR src */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 1);
+ BIT_OPC (sc, bit, b ^ carry);
+
+ /* 0000 0001 1000 ddd w dd11 1110 CLIP.size #IMM1,#IMM2,dest */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ a = sign_ext (IMM(w+1), w*8+8);
+ b = sign_ext (IMM(w+1), w*8+8);
+ v = sign_ext (get_src (dc), w*8+8);
+ tprintf("clip %d <= %d <= %d : ", a, v, b);
+ if (a > v)
+ v = a;
+ if (v > b)
+ v = b;
+ tprintf("%d\n", v);
+ put_dest (dc, v);
+
+ /* 1001 ddd w dd10 1110 CMP.size:G #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ v = get_src (dc);
+ imm = IMM(w+1);
+ cmp (v, imm, w+1);
+
+ /* 1010 ddd0 dd11 0001 CMP.L:G #IMM32,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, 4);
+ v = get_src (dc);
+ imm = IMM(4);
+ cmp (v, imm, 4);
+
+ /* 1110 ddd w dd01 immm CMP.size:Q #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ v = get_src (dc);
+ immm = sign_ext (immm, 4);
+ cmp (v, immm, w+1);
+
+ /* 01dd 011w CMP.size:S #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest2 (dd, w+1);
+ v = get_src (dc);
+ imm = sign_ext (IMM(w+1),w*8+8);
+ cmp (v, imm, w+1);
+
+ /* 1sss ddd w dd ss 0110 CMP.size:G src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23 (sss, ss, w+1);
+ dc = decode_dest23 (ddd, dd, w+1);
+ a = get_src (dc);
+ b = get_src (sc);
+ cmp (a, b, w+1);
+
+ /* 1sss ddd1 dd ss 0001 CMP.L:G src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23 (sss, ss, 4);
+ dc = decode_dest23 (ddd, dd, 4);
+ a = get_src (dc);
+ b = get_src (sc);
+ cmp (a, b, 4);
+
+ /* 01dd 000w CMP.size:S src,R0/R0L */
+
+ prefix (0, 1, 0);
+ dc = decode_dest2 (dd, w+1);
+ a = get_reg (w ? r0 : r0l);
+ b = get_src (dc);
+ cmp (a, b, w+1);
+
+ /* 1010 ddd0 dd01 0001 CMPX #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, 4);
+ v = get_src (dc);
+ imm = sign_ext (IMM(1), 8);
+ cmp (v, imm, 4);
+
+ /* 0000 0001 1000 ddd w dd00 1110 DADC.size #IMM,dest */
+
+ DADDI(1,1);
+
+ /* 0000 0001 1sss ddd w dd ss 1000 DADC.size src,dest */
+
+ DADDV(1,1);
+
+ /* 0000 0001 1000 ddd w dd01 1110 DADD.size #IMM,dest */
+
+ DADDI(1,0);
+
+ /* 0000 0001 1sss ddd w dd ss 0000 DADD.size src,dest */
+
+ DADDV(1,0);
+
+ /* 1011 ddd w dd00 1110 DEC.size dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ a = get_src (dc);
+ v = a-1;
+ tprintf ("%x -- = %x\n", a, v);
+ set_sz (v, w+1);
+ put_dest (dc, v);
+
+ /* 1011 0000 010w 0011 DIV.size #IMM */
+
+ prefix (0, 0, 0);
+ div_op (-1, 0, 0, 0, w+1);
+
+ /* 1000 sss w ss01 1110 DIV.size src */
+
+ prefix (0, 1, 0);
+ div_op (sss, ss, 0, 0, w+1);
+
+ /* 0000 0001 1010 sss1 ss01 1111 DIV.L src */
+
+ M32C_ONLY();
+ prefix (0, 0, 0);
+ div_op (sss, ss, 0, 0, 4);
+
+ /* 1011 0000 000w 0011 DIVU.size #IMM */
+
+ prefix (0, 0, 0);
+ div_op (-1, 0, 1, 0, w+1);
+
+ /* 1000 sss w ss00 1110 DIVU.size src */
+
+ prefix (0, 1, 0);
+ div_op (sss, ss, 1, 0, w+1);
+
+ /* 0000 0001 1010 sss1 ss00 1111 DIVU.L src */
+
+ M32C_ONLY();
+ prefix (0, 0, 0);
+ div_op (sss, ss, 1, 0, 4);
+
+ /* 1011 0010 010w 0011 DIVX.size #IMM */
+
+ prefix (0, 0, 0);
+ div_op (-1, 0, 0, 1, w+1);
+
+ /* 1001 sss w ss01 1110 DIVX.size src */
+
+ prefix (0, 1, 0);
+ div_op (sss, ss, 0, 1, w+1);
+
+ /* 0000 0001 1010 sss1 ss10 1111 DIVX.L src */
+
+ M32C_ONLY();
+ prefix (0, 0, 0);
+ div_op (sss, ss, 0, 1, 4);
+
+ /* 0000 0001 1001 ddd w dd00 1110 DSBB.size #IMM,dest */
+
+ DADDI(0,1);
+
+ /* 0000 0001 1sss ddd w dd ss 1010 DSBB.size src,dest */
+
+ DADDV(0,1);
+
+ /* 0000 0001 1001 ddd w dd01 1110 DSUB.size #IMM,dest */
+
+ DADDI(0,0);
+
+ /* 0000 0001 1sss ddd w dd ss 0010 DSUB.size src,dest */
+
+ DADDV(0,0);
+
+ /* 1110 1100 ENTER #IMM */
+
+ imm = IMM(1);
+ put_reg (sp, get_reg (sp) - 4);
+ mem_put_si (get_reg (sp), get_reg (fb));
+ put_reg (fb, get_reg (sp));
+ put_reg (sp, get_reg (sp) - imm);
+
+ /* 1111 1100 EXITD */
+
+ put_reg (sp, get_reg (fb));
+ put_reg (fb, mem_get_si (get_reg (sp)));
+ put_reg (sp, get_reg (sp) + 4);
+ put_reg (pc, mem_get_si (get_reg (sp)));
+ put_reg (sp, get_reg (sp) + 4);
+
+ /* 1100 ddd w dd01 1110 EXTS.size dest */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ v = sign_ext (get_src (dc), (w+1)*8);
+ dc = widen_sd (dc);
+ put_dest (dc, v);
+ set_sz (v, (w+1)*2);
+
+ /* 0000 0001 1sss ddd0 dd ss 0111 EXTS.B src,dest */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 1);
+ dc = decode_dest23 (ddd, dd, 2);
+ v = sign_ext (get_src (sc), 8);
+ put_dest (dc, v);
+ set_sz (v, 16);
+
+ /* 0000 0001 1sss ddd0 dd ss 1011 EXTZ src,dest */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 1);
+ dc = decode_dest23 (ddd, dd, 2);
+ v = get_src (sc);
+ put_dest (dc, v);
+ set_sz (v, 16);
+
+ /* 1101 0011 1110 1dst FCLR dest */
+
+ set_flags (1 << dst, 0);
+
+ /* 1001 1111 FREIT */
+
+ NOTYET();
+
+ /* 1101 0001 1110 1dst FSET dest */
+
+ set_flags (1 << dst, 1 << dst);
+
+ /* 1010 ddd w dd00 1110 INC.size dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ a = get_src (dc);
+ v = a+1;
+ tprintf ("%x ++ = %x\n", a, v);
+ set_sz (v, w+1);
+ put_dest (dc, v);
+
+ /* 1000 sss0 ss0w 0011 INDEXB.size src */
+ INDEXOP(1, 1, 1);
+ /* 1010 sss0 ss0w 0011 INDEXBD.size src */
+ INDEXOP(1, 0, 1);
+ /* 1100 sss0 ss0w 0011 INDEXBS.size src */
+ INDEXOP(1, 1, 0);
+ /* 1001 sss0 ss1w 0011 INDEXL.size src */
+ INDEXOP(4, 1, 1);
+ /* 1011 sss0 ss1w 0011 INDEXLD.size src */
+ INDEXOP(4, 0, 1);
+ /* 1001 sss0 ss0w 0011 INDEXLS.size src */
+ INDEXOP(4, 1, 0);
+ /* 1000 sss0 ss1w 0011 INDEXW.size src */
+ INDEXOP(2, 1, 1);
+ /* 1010 sss0 ss1w 0011 INDEXWD.size src */
+ INDEXOP(2, 0, 1);
+ /* 1100 sss0 ss1w 0011 INDEXWS.size src */
+ INDEXOP(2, 1, 0);
+
+ /* 1011 1110 vector00 INT #IMM */
+
+ prefix (0, 0, 0);
+ trigger_based_interrupt (vector);
+
+ /* 1011 1111 INTO */
+
+ prefix (0, 0, 0);
+ if (FLAG_O)
+ trigger_fixed_interrupt (0xffffe0);
+
+ /* 1ccc 101c Jcnd label */
+
+ prefix (0, 0, 0);
+ v = sign_ext (IMM(1), 8);
+ if (condition_true (ccc*2+c))
+ put_reg (pc, orig_pc + 1 + v);
+
+ /* 01dd 101d JMP.S label */
+
+ prefix (0, 0, 0);
+ put_reg (pc, orig_pc + (dd*2+d) + 2);
+
+ /* 1011 1011 JMP.B label */
+
+ prefix (0, 0, 0);
+ imm = sign_ext (IMM(1), 8);
+ if (imm == -1)
+ {
+ if (verbose)
+ printf("[jmp-to-self detected as exit]\n");
+ return M32C_MAKE_HIT_BREAK ();
+ }
+ put_reg (pc, orig_pc + 1 + imm);
+
+ /* 1100 1110 JMP.W label */
+
+ prefix (0, 0, 0);
+ imm = sign_ext (IMM(2), 16);
+ put_reg (pc, orig_pc + 1 + imm);
+
+ /* 1100 1100 JMP.A label */
+
+ prefix (0, 0, 0);
+ imm = IMM(3);
+ put_reg (pc, imm);
+
+ /* 1100 sss1 ss00 1111 JMPI.W src */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 2);
+ a = get_src (sc);
+ a = sign_ext (a, 16);
+ put_reg (pc, orig_pc + a);
+
+ /* 1000 sss0 ss00 0001 JMPI.A src */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 3);
+ a = get_src (sc);
+ put_reg (pc, a);
+
+ /* 1101 1100 JMPS #IMM8 */
+
+ prefix (0, 0, 0);
+ imm = IMM(1);
+ a = 0xff0000 + mem_get_hi (0xfffe00 - imm * 2);
+ put_reg (pc, a);
+
+ /* 1100 1111 JSR.W label */
+
+ prefix (0, 0, 0);
+ imm = sign_ext (IMM(2), 16);
+ put_reg (sp, get_reg (sp) - 4);
+ mem_put_si (get_reg (sp), get_reg (pc));
+ put_reg (pc, orig_pc + imm + 1);
+
+ /* 1100 1101 JSR.A label */
+
+ prefix (0, 0, 0);
+ imm = IMM(3);
+ put_reg (sp, get_reg (sp) - 4);
+ mem_put_si (get_reg (sp), get_reg (pc));
+ put_reg (pc, imm);
+
+ /* 1100 sss1 ss01 1111 JSRI.W src */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 2);
+ a = get_src (sc);
+ a = sign_ext (a, 16);
+ put_reg (sp, get_reg (sp) - 4);
+ mem_put_si (get_reg (sp), get_reg (pc));
+ put_reg (pc, orig_pc + a);
+
+ /* 1001 sss0 ss00 0001 JSRI.A src */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 3);
+ a = get_src (sc);
+ put_reg (sp, get_reg (sp) - 4);
+ mem_put_si (get_reg (sp), get_reg (pc));
+ put_reg (pc, a);
+
+ /* 1101 1101 JSRS #IMM8 */
+
+ prefix (0, 0, 0);
+ imm = IMM(1);
+ a = 0xff0000 + mem_get_hi (0xfffe00 - imm * 2);
+ put_reg (sp, get_reg (sp) - 4);
+ mem_put_si (get_reg (sp), get_reg (pc));
+ put_reg (pc, a);
+
+ /* 1101 0101 1010 1dst LDC #IMM16,dest */
+
+ imm = IMM(2);
+ dc = decode_cr_b (dst, CR_B_DCT0);
+ put_dest (dc, imm);
+
+ /* 1101 0101 0010 1dst LDC #IMM24,dest */
+
+ imm = IMM(3);
+ dc = decode_cr_b (dst, CR_B_INTB);
+ put_dest (dc, imm);
+
+ /* 1101 0101 0110 1dst LDC #IMM24,dest */
+
+ imm = IMM(3);
+ dc = decode_cr_b (dst, CR_B_DMA0);
+ put_dest (dc, imm);
+
+ /* 0000 0001 1101 sss1 ss00 1dst LDC src,dest */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 2);
+ dc = decode_cr_b (dst, CR_B_DCT0);
+ a = get_src (sc);
+ put_dest (dc, a);
+
+ /* 1101 sss1 ss00 0dst LDC src,dest */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 3);
+ dc = decode_cr_b (dst, CR_B_INTB);
+ a = get_src (sc);
+ put_dest (dc, a);
+
+ /* 0000 0001 1101 sss1 ss00 0dst LDC src,dest */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 3);
+ dc = decode_cr_b (dst, CR_B_DMA0);
+ a = get_src (sc);
+ put_dest (dc, a);
+
+ /* 1011 0110 1100 0011 LDCTX */
+
+ NOTYET();
+
+ /* 1101 0101 1110 1imm LDIPL #IMM */
+
+ set_flags (0x7000, imm*0x1000);
+
+ /* 0000 0001 1000 ddd w dd11 1111 MAX.size #IMM,dest */
+
+ prefix (0, 0, 0);
+ w++;
+ dc = decode_dest23 (ddd, dd, w);
+ imm = sign_ext (IMM(w), w*8);
+ a = sign_ext (get_src (dc), w*8);
+ tprintf ("max %d %d\n", imm, a);
+ if (imm > a)
+ put_dest (dc, imm);
+
+ /* 0000 0001 1sss ddd w dd ss 1101 MAX.size src,dest */
+
+ prefix (0, 0, 0);
+ w++;
+ sc = decode_src23 (sss, ss, w);
+ dc = decode_dest23 (ddd, dd, w);
+ b = sign_ext (get_src (sc), w*8);
+ a = sign_ext (get_src (dc), w*8);
+ tprintf ("max %d %d\n", b, a);
+ if (b > a)
+ put_dest (dc, b);
+
+ /* 0000 0001 1000 ddd w dd10 1111 MIN.size #IMM,dest */
+
+ prefix (0, 0, 0);
+ w++;
+ dc = decode_dest23 (ddd, dd, w);
+ imm = sign_ext (IMM(w), w*8);
+ a = sign_ext (get_src (dc), w*8);
+ tprintf ("min %d %d\n", imm, a);
+ if (imm < a)
+ put_dest (dc, imm);
+
+ /* 0000 0001 1sss ddd w dd ss 1100 MIN.size src,dest */
+
+ prefix (0, 0, 0);
+ w++;
+ sc = decode_src23 (sss, ss, w);
+ dc = decode_dest23 (ddd, dd, w);
+ b = sign_ext (get_src (sc), w*8);
+ a = sign_ext (get_src (dc), w*8);
+ tprintf ("min %d %d\n", b, a);
+ if (b < a)
+ put_dest (dc, b);
+
+ /* 1001 ddd w dd10 1111 MOV.size:G #IMM,dest */
+
+ dc = decode_dest23 (ddd, dd, w+1);
+ imm = IMM(w+1);
+ v = imm;
+ tprintf("%x = %x\n", v, v);
+ set_sz(v, w+1);
+ put_dest (dc, v);
+
+ /* 1011 ddd0 dd11 0001 MOV.L:G #IMM,dest */
+
+ dc = decode_dest23 (ddd, dd, 4);
+ imm = IMM(4);
+ v = imm;
+ tprintf("%x = %x\n", v, v);
+ set_sz(v, 4);
+ put_dest (dc, v);
+
+ /* 1111 ddd w dd10 immm MOV.size:Q #IMM4,dest */
+
+ dc = decode_dest23 (ddd, dd, w+1);
+ imm = sign_ext (immm, 4);
+ v = imm;
+ tprintf("%x = %d\n", v, v);
+ set_sz(v, w+1);
+ put_dest (dc, v);
+
+ /* 00dd 010w MOV.size:S #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest2 (dd, w+1);
+ imm = IMM(w+1);
+ put_dest (dc, imm);
+ set_sz (imm, w+1);
+
+ /* 10w1 110d MOV.size:S #IMM,a0/a1 */
+
+ imm = IMM(w ? 3 : 2);
+ put_reg (d ? a1 : a0, imm);
+ set_sz (imm & addr_mask, w+1);
+
+ /* 00dd 001w MOV.size:Z #0,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest2 (dd, w+1);
+ put_dest (dc, 0);
+ set_sz (0, w+1);
+
+ /* 1sss ddd w dd ss 1011 MOV.size:G src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23 (sss, ss, w+1);
+ dc = decode_dest23 (ddd, dd, w+1);
+ v = get_src (sc);
+ put_dest (dc, v);
+ set_sz (v, w+1);
+
+ /* 1sss ddd1 dd ss 0011 MOV.L:G src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23 (sss, ss, 4);
+ dc = decode_dest23 (ddd, dd, 4);
+ v = get_src (sc);
+ put_dest (dc, v);
+ set_sz (v, 4);
+
+ /* VARY SS 01 10 11 */
+ /* 00SS 100w MOV.size:S src,R0L/R0 */
+
+ prefix (0, 1, 0);
+ sc = decode_dest2 (SS, w+1);
+ v = get_src (sc);
+ put_reg (w ? r0 : r0l, v);
+ set_sz (v, w+1);
+
+ /* 01ss 111w MOV.size:S src,R1L/R1 */
+
+ prefix (0, 1, 0);
+ sc = decode_dest2 (ss, w+1);
+ v = get_src (sc);
+ put_reg (w ? r1 : r1l, v);
+ set_sz (v, w+1);
+
+ /* VARY DD 01 10 11 */
+ /* 00DD 000w MOV.size:S R0L/R0,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest2 (DD, w+1);
+ v = get_reg (w ? r0 : r0l);
+ put_dest (dc, v);
+ set_sz (v, w+1);
+
+ /* 01ss 100d MOV.L:S src,A0/A1 */
+
+ prefix (0, 1, 0);
+ sc = decode_dest2 (ss, 4);
+ v = get_src (sc);
+ put_reg (d ? a1 : a0, v);
+ set_sz (v, 4);
+
+ /* 1011 ddd w dd00 1111 MOV.size:G dsp:8[SP], dest */
+
+ prefix (0, 0, 0);
+ imm = IMM(1);
+ dc = decode_dest23 (ddd, dd, w+1);
+ a = get_reg (sp) + sign_ext (imm, 8);
+ a &= addr_mask;
+ if (w)
+ v = mem_get_hi (a);
+ else
+ v = mem_get_qi (a);
+ put_dest (dc, v);
+ set_sz (v, w+1);
+
+ /* 1010 sss w ss00 1111 MOV.size:G src,dsp:8[SP] */
+
+ prefix (0, 0, 0);
+ sc = decode_dest23 (sss, ss, w+1);
+ imm = IMM(1);
+ a = get_reg (sp) + sign_ext (imm, 8);
+ a &= addr_mask;
+ v = get_src (sc);
+ if (w)
+ mem_put_hi (a, v);
+ else
+ mem_put_qi (a, v);
+ set_sz (v, w+1);
+
+ /* 1101 sss1 ss01 1dst MOVA src,dest */
+
+ static reg_id map[8] = { r2r0, r3r1, a0, a1 };
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 1);
+ if (!sc.mem || !map[dst])
+ UNSUPPORTED();
+ put_reg (map[dst], sc.u.addr);
+
+ /* 0000 0001 1011 ddd0 dd hl 1110 MOVdir R0L,dest */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, 1);
+ a = get_src (dc);
+ b = get_reg (r0l);
+ switch (hl)
+ {
+ case 0: a = (a & 0xf0) | (b & 0x0f); break;
+ case 1: a = (a & 0xf0) | ((b>>4) & 0x0f); break;
+ case 2: a = (a & 0x0f) | ((b & 0x0f)<<4); break;
+ case 3: a = (a & 0x0f) | (b & 0xf0); break;
+ }
+ put_dest (dc, a);
+
+ /* 0000 0001 1010 sss0 ss hl 1110 MOVdir src,R0L */
+
+ prefix (0, 0, 0);
+ sc = decode_dest23 (sss, ss, 1);
+ a = get_reg (r0l);
+ b = get_src (dc);
+ switch (hl)
+ {
+ case 0: a = (a & 0xf0) | (b & 0x0f); break;
+ case 1: a = (a & 0xf0) | ((b>>4) & 0x0f); break;
+ case 2: a = (a & 0x0f) | ((b & 0x0f)<<4); break;
+ case 3: a = (a & 0x0f) | (b & 0xf0); break;
+ }
+ put_reg (r0l, a);
+
+ /* 1011 ddd0 dd01 0001 MOVX #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, 4);
+ imm = sign_ext (IMM(1), 8);
+ put_dest (dc, imm);
+ set_sz (imm, 1);
+
+ /* 1000 ddd w dd01 1111 MUL.size #IMM,dest */
+
+ prefix (0, 1, 0);
+ w ++;
+ dc = decode_dest23 (ddd, dd, w);
+ v = sign_ext (get_src (dc), w*8);
+ imm = sign_ext (IMM(w), w*8);
+ tprintf("%d * %d = %d\n", v, imm, v*imm);
+ v *= imm;
+ dc = widen_sd (dc);
+ put_dest (dc, v);
+
+ /* 1sss ddd w dd ss 1100 MUL.size src,dest */
+
+ prefix (1, 1, 0);
+ w ++;
+ sc = decode_src23 (sss, ss, w);
+ dc = decode_dest23 (ddd, dd, w);
+ a = sign_ext (get_src (sc), w*8);
+ b = sign_ext (get_src (dc), w*8);
+ tprintf("%d * %d = %d\n", a, b, a*b);
+ v = a * b;
+ dc = widen_sd (dc);
+ put_dest (dc, v);
+
+ /* 0000 0001 1000 sss1 ss01 1111 MUL.L src,R2R0 */
+
+ M32C_ONLY();
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 4);
+ a = sign_ext (get_src (sc), 32);
+ b = sign_ext (get_reg (r2r0), 32);
+ ll = (long long)a * (long long)b;
+ tprintf("%d * %d = %lld (%llx)\n", a, b, ll, ll);
+ if (ll < b2minsigned[4] || ll > b2maxsigned[4])
+ set_flags (FLAGBIT_O, FLAGBIT_O);
+ else
+ set_flags (FLAGBIT_O, 0);
+ put_reg (r2r0, (int)ll);
+
+ /* 1100 sss1 ss11 1110 MULEX src */
+
+ prefix (0, 1, 0);
+ sc = decode_dest23 (sss, ss, 2);
+ a = sign_ext (get_src (sc), 16);
+ b = sign_ext (get_reg (r2r0), 32);
+ ll = (long long)a * (long long)b;
+ tprintf("%d * %d = %lld (%llx)\n", a, b, ll, ll);
+ put_reg (r2r0, (int)ll);
+ put_reg (r1, (int)(ll >> 32));
+
+ /* 1000 ddd w dd00 1111 MULU.size #IMM,dest */
+
+ prefix (0, 1, 0);
+ w ++;
+ dc = decode_dest23 (ddd, dd, w);
+ v = get_src (dc);
+ imm = IMM(w);
+ tprintf("%d * %d = %d\n", v, imm, v*imm);
+ v *= imm;
+ dc = widen_sd (dc);
+ put_dest (dc, v);
+
+ /* 1sss ddd w dd ss 0100 MULU.size src,dest */
+
+ prefix (1, 1, 0);
+ w ++;
+ sc = decode_src23 (sss, ss, w);
+ dc = decode_dest23 (ddd, dd, w);
+ a = get_src (sc);
+ b = get_src (dc);
+ tprintf("%d * %d = %d\n", a, b, a*b);
+ v = a * b;
+ dc = widen_sd (dc);
+ put_dest (dc, v);
+
+ /* 0000 0001 1000 sss1 ss00 1111 MULU.L src,R2R0 */
+
+ M32C_ONLY();
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, 4);
+ a = get_src (sc);
+ b = get_reg (r2r0);
+ ll = (long long)a * (long long)b;
+ tprintf("%d * %d = %lld (%llx)\n", a, b, ll, ll);
+ if (ll < b2minsigned[4] || ll > b2maxsigned[4])
+ set_flags (FLAGBIT_O, FLAGBIT_O);
+ else
+ set_flags (FLAGBIT_O, 0);
+ put_reg (r2r0, (int)ll);
+
+ /* 1010 ddd w dd10 1111 NEG.size dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ a = sign_ext (get_src (dc), (w+1)*8);
+ v = -a;
+ tprintf("%d * -1 = %d\n", a, v);
+ set_oszc(v, w+1, v==0);
+ put_dest (dc, v);
+
+ /* 1101 1110 NOP */
+
+ tprintf("nop\n");
+
+ /* 1010 ddd w dd01 1110 NOT.size dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ a = get_src (dc);
+ v = ~a;
+ tprintf("~ %x = %x\n", a, v);
+ set_sz(v, w+1);
+ put_dest (dc, v);
+
+ /* 1000 ddd w dd10 1111 OR.size:G #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23(ddd, dd, w+1);
+ imm = IMM(w+1);
+ LOGIC_OP (dc, imm, |);
+
+ /* 01dd 010w OR.size:S #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest2(dd, w+1);
+ imm = IMM (w+1);
+ LOGIC_OP (dc, imm, |);
+
+ /* 1sss ddd w dd ss 0101 OR.size:G src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23(sss, ss, w+1);
+ dc = decode_dest23(ddd, dd, w+1);
+ b = get_src (sc);
+ LOGIC_OP (dc, b, |);
+
+ /* 1011 ddd w dd10 1111 POP.size dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ if (w)
+ a = mem_get_hi (get_reg (sp));
+ else
+ a = mem_get_qi (get_reg (sp));
+ put_reg (sp, get_reg (sp) + 2);
+ tprintf("pop%s: %x\n", w ? "hi" : "qi", a);
+ put_dest (dc, a);
+
+ /* 1101 0011 1010 1dst POPC dest */
+
+ prefix (0, 0, 0);
+ dc = decode_cr_b (dst, CR_B_DCT0);
+ a = mem_get_hi (get_reg (sp));
+ put_reg (sp, get_reg (sp) + 2);
+ tprintf("pophi: %x\n", a);
+ put_dest (dc, a);
+
+ /* 1101 0011 0010 1dst POPC dest */
+
+ prefix (0, 0, 0);
+ dc = decode_cr_b (dst, CR_B_INTB);
+ a = mem_get_si (get_reg (sp));
+ put_reg (sp, get_reg (sp) + 4);
+ tprintf("popsi: %x\n", a);
+ put_dest (dc, a);
+
+ /* 1000 1110 POPM dest */
+
+ static int map[] = { r0, r1, r2, r3, a0, a1, sb, fb };
+ prefix (0, 0, 0);
+ imm = IMM(1);
+ tprintf("popm: %x\n", imm);
+ for (a=0; a<4; a++)
+ if (imm & (1<<a))
+ {
+ v = mem_get_hi (get_reg (sp));
+ put_reg (map[a], v);
+ put_reg (sp, get_reg (sp) + 2);
+ }
+ for (; a<8; a++)
+ if (imm & (1<<a))
+ {
+ v = mem_get_si (get_reg (sp));
+ put_reg (map[a], v);
+ put_reg (sp, get_reg (sp) + 4);
+ }
+
+ /* 1010 111w PUSH.size #IMM */
+
+ prefix (0, 0, 0);
+ imm = IMM(w+1);
+ tprintf("push%s: %x\n", w ? "hi" : "qi", imm);
+ int a = get_reg (sp) - 2;
+ if (w)
+ mem_put_hi (a, imm);
+ else
+ mem_put_qi (a, imm);
+ put_reg (sp, a);
+
+ /* 1100 sss w ss00 1110 PUSH.size src */
+
+ prefix (0, 1, 0);
+ sc = decode_dest23 (sss, ss, w+1);
+ a = get_src (sc);
+ put_reg (sp, get_reg (sp) - 2);
+ if (w)
+ mem_put_hi (get_reg (sp), a);
+ else
+ mem_put_qi (get_reg (sp), a);
+ tprintf("push%s: %x\n", w ? "hi" : "qi", a);
+
+ /* 1011 0110 0101 0011 PUSH.L #IMM32 */
+
+ imm = IMM(4);
+ put_reg (sp, get_reg (sp) - 4);
+ mem_put_si (get_reg (sp), imm);
+
+ /* 1010 sss0 ss00 0001 PUSH.L src */
+
+ prefix (0, 1, 0);
+ sc = decode_dest23 (sss, ss, 4);
+ a = get_src (sc);
+ put_reg (sp, get_reg (sp) - 4);
+ mem_put_si (get_reg (sp), a);
+
+ /* 1011 0sa0 ss00 0001 PUSHA src */
+
+ prefix (0, 0, 0);
+ sc = decode_dest23 (sa, ss, 1);
+ put_reg (sp, get_reg (sp) - 4);
+ mem_put_hi (get_reg (sp), sc.u.addr);
+ tprintf("pushsi: %x\n", sc.u.addr);
+
+ /* 1101 0001 1010 1src PUSHC src */
+
+ prefix (0, 0, 0);
+ sc = decode_cr_b (src, CR_B_DCT0);
+ a = get_src (sc);
+ put_reg (sp, get_reg (sp) - 2);
+ mem_put_hi (get_reg (sp), a);
+ tprintf("pushhi: %x\n", a);
+
+ /* 1101 0001 0010 1src PUSHC src */
+
+ prefix (0, 0, 0);
+ sc = decode_cr_b (src, CR_B_INTB);
+ a = get_src (sc);
+ put_reg (sp, get_reg (sp) - 4);
+ mem_put_si (get_reg (sp), a);
+ tprintf("pushsi: %x\n", a);
+
+ /* 1000 1111 PUSHM src */
+
+ static int map[] = { fb, sb, a1, a0, r3, r2, r1, r0 };
+ imm = IMM(1);
+ tprintf("pushm: %x\n", imm);
+ for (a=0; a<4; a++)
+ if (imm & (1<<a))
+ {
+ put_reg (sp, get_reg (sp) - 4);
+ v = get_reg (map[a]);
+ mem_put_si (get_reg (sp), v);
+ }
+ for (; a<8; a++)
+ if (imm & (1<<a))
+ {
+ put_reg (sp, get_reg (sp) - 2);
+ v = get_reg (map[a]);
+ mem_put_hi (get_reg (sp), v);
+ }
+
+ /* 1001 1110 REIT */
+
+ a = get_reg (sp);
+ put_reg (pc, mem_get_si (a));
+ a += 4;
+ put_reg (flags, mem_get_hi (a));
+ a += 2;
+ put_reg (sp, a);
+
+ /* 1011 1000 010w 0011 RMPA.size */
+
+ int count = get_reg (r3);
+ int list1 = get_reg (a0);
+ int list2 = get_reg (a1);
+ long long sum = get_reg_ll (r3r1r2r0) & 0xffffff;
+
+ while (count)
+ {
+ if (w)
+ {
+ a = sign_ext (mem_get_hi (list1), 16);
+ b = sign_ext (mem_get_hi (list2), 16);
+ }
+ else
+ {
+ a = sign_ext (mem_get_qi (list1), 8);
+ b = sign_ext (mem_get_qi (list2), 8);
+ }
+ tprintf("%lld + %d * %d = ", sum, a, b);
+ sum += a * b;
+ tprintf("%lld\n", sum);
+ list1 += w ? 2 : 1;
+ list2 += w ? 2 : 1;
+ count --;
+ }
+ put_reg (r3, count);
+ put_reg (a0, list1);
+ put_reg (a1, list2);
+ put_reg (r2r0, (int)(sum & 0xffffffffU));
+ put_reg (r1, (int)(sum >> 32));
+
+ /* 1011 ddd w dd10 1110 ROLC.size dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ rot_op (dc, 1, 1);
+
+ /* 1010 ddd w dd10 1110 RORC.size dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ rot_op (dc, 1, -1);
+
+ /* 1110 ddd w dd10 immm ROT.size #IMM, dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ rot_op (dc, IMM4(), -1);
+
+ /* 1010 ddd w dd11 1111 ROT.size R1H,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ a = sign_ext (get_reg (r1h), 8);
+ rot_op (dc, a, -1);
+
+ /* 1101 1111 RTS */
+
+ put_reg (pc, mem_get_si (get_reg (sp)));
+ put_reg (sp, get_reg (sp) + 4);
+
+ /* 0000 0001 1001 ddd w dd10 1110 SBB.size #IMM, dest */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ imm = IMM (w+1);
+ MATH_OP (dc, imm, !carry, -);
+
+ /* 0000 0001 1sss ddd w dd ss 0110 SBB.size src,dest */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, w+1);
+ dc = decode_dest23 (ddd, dd, w+1);
+ MATH_OP (dc, get_src (sc), !carry, -);
+
+ /* 1101 ddd1 dd11 cond SCcond dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, 2);
+ if (condition_true (cond))
+ put_dest (dc, 1);
+ else
+ put_dest (dc, 0);
+
+ /* 1011 1000 110w 0011 SCMPU.size */
+
+ ta0 = get_reg (a0);
+ ta1 = get_reg (a1);
+
+ for (;;)
+ {
+ t0 = mem_get_qi (ta0);
+ t2 = mem_get_qi (ta1);
+ if (w)
+ {
+ t1 = mem_get_qi (ta0 + 1);
+ t3 = mem_get_qi (ta1 + 1);
+ }
+ dif = t0 - t2;
+ if (dif == 0 && t0 != 0 && w)
+ dif = t1 - t3;
+ set_oszc (dif, 1, dif > 0);
+
+ ta0 += w ? 2 : 1;
+ ta1 += w ? 2 : 1;
+
+ if (t0 == 0 || t0 != t2)
+ break;
+ if (w && (t1 == 0 || t1 != t3))
+ break;
+ }
+
+ /* 1111 ddd w dd00 immm SHA.size #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ shift_op (dc, 1, IMM4(), 1);
+
+ /* 1010 ddd0 dd10 0001 SHA.L #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, 4);
+ imm = sign_ext (IMM(1), 8);
+ shift_op (dc, 1, imm, 1);
+
+ /* 1011 ddd w dd11 1110 SHA.size R1H,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ a = sign_ext (get_reg (r1h), 8);
+ shift_op (dc, 1, a, 1);
+
+ /* 1100 ddd0 dd01 0001 SHA.L R1H,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, 4);
+ a = sign_ext (get_reg (r1h), 8);
+ shift_op (dc, 1, a, 1);
+
+ /* 1100 ddd0 dd10 0001 SHANC.L #IMM,dest */
+
+ M32C_ONLY();
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, 4);
+ imm = sign_ext (IMM(1), 8);
+ shift_op (dc, 1, imm, 0);
+
+ /* 1110 ddd w dd00 immm SHL.size #IMM, dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ shift_op (dc, 0, IMM4(), 1);
+
+ /* 1001 ddd0 dd10 0001 SHL.L #IMM, dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, 4);
+ imm = sign_ext (IMM(1), 8);
+ shift_op (dc, 0, imm, 1);
+
+ /* 1010 ddd w dd11 1110 SHL.size R1H,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ a = sign_ext (get_reg (r1h), 8);
+ shift_op (dc, 0, a, 1);
+
+ /* 1100 ddd0 dd00 0001 SHL.L R1H,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, 4);
+ a = sign_ext (get_reg (r1h), 8);
+ shift_op (dc, 0, a, 1);
+
+ /* 1000 ddd0 dd10 0001 SHLNC.L #IMM,dest */
+
+ M32C_ONLY();
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, 4);
+ imm = sign_ext (IMM(1), 8);
+ shift_op (dc, 0, imm, 0);
+
+ /* 1011 0010 100w 0011 SIN.size */
+
+ v = get_reg (a0);
+ a = get_reg (a1);
+ b = get_reg (r3);
+ if (b) for (;b;)
+ {
+ if (w)
+ mem_put_hi(a, mem_get_hi (v));
+ else
+ mem_put_qi(a, mem_get_qi (v));
+ a += w ? 2 : 1;
+ b --;
+ }
+ put_reg (a0, v);
+ put_reg (a1, a);
+ put_reg (r3, b);
+
+ /* 1011 0110 100w 0011 SMOVB.size */
+
+ v = get_reg (a0);
+ a = get_reg (a1);
+ b = get_reg (r3);
+ if (b) for (;b;)
+ {
+ if (w)
+ mem_put_hi(a, mem_get_hi (v));
+ else
+ mem_put_qi(a, mem_get_qi (v));
+ v -= w ? 2 : 1;
+ a -= w ? 2 : 1;
+ b --;
+ }
+ put_reg (a0, v);
+ put_reg (a1, a);
+ put_reg (r3, b);
+
+ /* 1011 0000 100w 0011 SMOVF.size */
+
+ v = get_reg (a0);
+ a = get_reg (a1);
+ b = get_reg (r3);
+ if (b) for (;b;)
+ {
+ if (w)
+ mem_put_hi(a, mem_get_hi (v));
+ else
+ mem_put_qi(a, mem_get_qi (v));
+ v += w ? 2 : 1;
+ a += w ? 2 : 1;
+ b --;
+ }
+ put_reg (a0, v);
+ put_reg (a1, a);
+ put_reg (r3, b);
+
+ /* 1011 1000 100w 0011 SMOVU.size */
+
+ v = get_reg (a0);
+ a = get_reg (a1);
+ do
+ {
+ if (w)
+ mem_put_hi(a, (t0 = mem_get_hi (v)));
+ else
+ mem_put_qi(a, (t0 = mem_get_qi (v)));
+ v += w ? 2 : 1;
+ a += w ? 2 : 1;
+ if (t0 == 0
+ || (w && ((t0 & 0xff) == 0 || (t0 & 0xff00) == 0)))
+ break;
+ } while (1);
+ put_reg (a0, v);
+ put_reg (a1, a);
+
+ /* 1011 0100 100w 0011 SOUT.size */
+
+ v = get_reg (a0);
+ a = get_reg (a1);
+ b = get_reg (r3);
+ for (;b;)
+ {
+ if (w)
+ mem_put_hi(a, mem_get_hi (v));
+ else
+ mem_put_qi(a, mem_get_qi (v));
+ v += w ? 2 : 1;
+ b --;
+ }
+ put_reg (a0, v);
+ put_reg (a1, a);
+ put_reg (r3, b);
+
+ /* 1011 1000 000w 0011 SSTR.size */
+
+ a = get_reg (a1);
+ b = get_reg (r3);
+ for (;b;)
+ {
+ if (w)
+ mem_put_hi(a, r0);
+ else
+ mem_put_qi(a, r0 & 0xff);
+ a += w ? 2 : 1;
+ b --;
+ }
+ put_reg (a1, a);
+ put_reg (r3, b);
+
+ /* 0000 0001 1101 ddd1 dd01 0src STC src,dest */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, 4);
+ sc = decode_cr_b (src, CR_B_DMA0);
+ a = get_src (sc);
+ put_dest (dc, a);
+
+ /* 0000 0001 1101 ddd1 dd01 1src STC src,dest */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, 2);
+ sc = decode_cr_b (src, CR_B_DCT0);
+ a = get_src (sc);
+ put_dest (dc, a);
+
+ /* 1101 ddd1 dd01 0src STC src,dest */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, 4);
+ sc = decode_cr_b (src, CR_B_INTB);
+ a = get_src (sc);
+ put_dest (dc, a);
+
+ /* 1011 0110 1101 0011 STCX abs16,abs24 */
+
+ NOTYET();
+
+ /* 1001 ddd w dd01 1111 STNZ.size #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ imm = IMM(w+1);
+ if (! FLAG_Z)
+ put_dest (dc, imm);
+
+ /* 1001 ddd w dd00 1111 STZ.size #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ imm = IMM(w+1);
+ if (FLAG_Z)
+ put_dest (dc, imm);
+
+ /* 1001 ddd w dd11 1111 STZX.size #IMM1,#IMM2,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ a = IMM(w+1);
+ b = IMM(w+1);
+ if (FLAG_Z)
+ put_dest (dc, a);
+ else
+ put_dest (dc, b);
+
+ /* 1000 ddd w dd11 1110 SUB.size:G #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23(ddd, dd, w+1);
+ imm = IMM(w+1);
+ MATH_OP (dc, imm, 0, -);
+
+ /* 1001 ddd0 dd11 0001 SUB.L:G #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23(ddd, dd, 4);
+ imm = IMM(4);
+ MATH_OP (dc, imm, 0, -);
+
+ /* 00dd 111w SUB.size:S #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest2(dd, w+1);
+ imm = IMM (w+1);
+ MATH_OP (dc, imm, 0, -);
+
+ /* 1sss ddd w dd ss 1010 SUB.size:G src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23(sss, ss, w+1);
+ dc = decode_dest23(ddd, dd, w+1);
+ b = get_src (sc);
+ MATH_OP (dc, b, 0, -);
+
+ /* 1sss ddd1 dd ss 0000 SUB.L:G src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23(sss, ss, 4);
+ dc = decode_dest23(ddd, dd, 4);
+ b = get_src (sc);
+ MATH_OP (dc, b, 0, -);
+
+ /* 1001 ddd0 dd01 0001 SUBX #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23(ddd, dd, 4);
+ imm = sign_ext (IMM(1), 8);
+ MATH_OP (dc, imm, 0, -);
+
+ /* 1sss ddd0 dd ss 0000 SUBX src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23(sss, ss, 1);
+ dc = decode_dest23(ddd, dd, 4);
+ b = sign_ext (get_src (sc), 8);
+ MATH_OP (dc, b, 0, -);
+
+ /* 1001 ddd w dd11 1110 TST.size:G #IMM,dest */
+
+ prefix (0, 0, 0);
+ dc = decode_dest23 (ddd, dd, w+1);
+ imm = IMM(w+1);
+ a = get_src (dc);
+ v = a & imm;
+ set_sz (v, w+1);
+
+ /* 00dd 110w TST.size:S #IMM,dest */
+
+ prefix (0, 0, 0);
+ dc = decode_dest2 (dd, w+1);
+ imm = IMM(w+1);
+ a = get_src (dc);
+ v = a & imm;
+ set_sz (v, w+1);
+
+ /* 0000 0001 1sss ddd w dd ss 1001 TST.size:G src,dest */
+
+ prefix (0, 0, 0);
+ sc = decode_src23 (sss, ss, w+1);
+ dc = decode_dest23 (ddd, dd, w+1);
+ b = get_src (sc);
+ a = get_src (dc);
+ v = a & b;
+ set_sz (v, w+1);
+
+ /* 1111 1111 UND */
+
+ trigger_fixed_interrupt (0xffffdc);
+
+ /* 1011 0010 0000 0011 WAIT */
+
+ ;
+
+ /* 1101 ddd w dd00 1src XCHG.size src,dest */
+
+ dc = decode_dest23 (ddd, dd, w+1);
+ sc = decode_src3 (src, w+1);
+ a = get_src (dc);
+ b = get_src (sc);
+ put_dest (dc, b);
+ put_dest (sc, a);
+
+ /* 1001 ddd w dd00 1110 XOR.size #IMM,dest */
+
+ prefix (0, 1, 0);
+ dc = decode_dest23(ddd, dd, w+1);
+ imm = IMM(w+1);
+ LOGIC_OP (dc, imm, ^);
+
+ /* 1sss ddd w dd ss 1001 XOR.size src,dest */
+
+ prefix (1, 1, 0);
+ sc = decode_src23(sss, ss, w+1);
+ dc = decode_dest23(ddd, dd, w+1);
+ b = get_src (sc);
+ LOGIC_OP (dc, b, ^);
+
+ /* */
+
+ return step_result;
+ }
Index: sim/m32c/main.c
===================================================================
RCS file: sim/m32c/main.c
diff -N sim/m32c/main.c
*** sim/m32c/main.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/main.c 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,114 ----
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <assert.h>
+ #include <setjmp.h>
+ #include <signal.h>
+
+ #include "bfd.h"
+
+ #include "cpu.h"
+ #include "mem.h"
+ #include "misc.h"
+ #include "load.h"
+ #include "trace.h"
+
+ static int disassemble = 0;
+ static unsigned int cycles = 0;
+
+ static void
+ done(int exit_code)
+ {
+ if (verbose)
+ {
+ stack_heap_stats();
+ mem_usage_stats();
+ printf("insns: %14s\n", comma(cycles));
+ }
+ exit(exit_code);
+ }
+
+ int
+ main(int argc, char **argv)
+ {
+ int o;
+ int save_trace;
+ bfd *prog;
+
+ while ((o = getopt(argc, argv, "tvdm:")) != -1)
+ switch (o)
+ {
+ case 't':
+ trace ++;
+ break;
+ case 'v':
+ verbose ++;
+ break;
+ case 'd':
+ disassemble ++;
+ break;
+ case 'm':
+ if (strcmp (optarg, "r8c") == 0
+ || strcmp (optarg, "m16c") == 0)
+ default_machine = bfd_mach_m16c;
+ else if (strcmp (optarg, "m32cm") == 0
+ || strcmp (optarg, "m32c") == 0)
+ default_machine = bfd_mach_m32c;
+ else
+ {
+ fprintf(stderr, "Invalid machine: %s\n", optarg);
+ exit(1);
+ }
+ break;
+ case '?':
+ fprintf(stderr, "usage: run [-v] [-t] [-d] [-m r8c||m16c|m32cm|m32c] program\n");
+ exit(1);
+ }
+
+ prog = bfd_openr (argv[optind], 0);
+ if (!prog)
+ {
+ fprintf(stderr, "Can't read %s\n", argv[optind]);
+ exit(1);
+ }
+
+ if (!bfd_check_format (prog, bfd_object))
+ {
+ fprintf(stderr, "%s not a m32c program\n", argv[optind]);
+ exit(1);
+ }
+
+ save_trace = trace;
+ trace = 0;
+ m32c_load (prog);
+ trace = save_trace;
+
+ if (disassemble)
+ sim_disasm_init (prog);
+
+ while (1)
+ {
+ int rc;
+
+ if (trace)
+ printf("\n");
+
+ if (disassemble)
+ sim_disasm_one();
+
+ enable_counting = verbose;
+ cycles ++;
+ rc = decode_opcode ();
+ enable_counting = 0;
+
+ if (M32C_HIT_BREAK (rc))
+ done(1);
+ else if (M32C_EXITED (rc))
+ done(M32C_EXIT_STATUS (rc));
+ else
+ assert (M32C_STEPPED (rc));
+
+ trace_register_changes ();
+ }
+ }
Index: sim/m32c/mem.c
===================================================================
RCS file: sim/m32c/mem.c
diff -N sim/m32c/mem.c
*** sim/m32c/mem.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/mem.c 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,347 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+
+ #include "mem.h"
+ #include "cpu.h"
+ #include "syscalls.h"
+ #include "misc.h"
+
+ #define L1_BITS (10)
+ #define L2_BITS (10)
+ #define OFF_BITS (12)
+
+ #define L1_LEN (1 << L1_BITS)
+ #define L2_LEN (1 << L2_BITS)
+ #define OFF_LEN (1 << OFF_BITS)
+
+ static unsigned char **pt[L1_LEN];
+
+ /* [ get=0/put=1 ][ byte size ] */
+ static unsigned int mem_counters[2][4];
+
+ #define COUNT(isput,bytes) if (verbose && enable_counting) mem_counters[isput][bytes]++
+
+ void
+ init_mem (void)
+ {
+ int i, j;
+
+ for (i = 0; i < L1_LEN; i++)
+ if (pt[i])
+ {
+ for (j = 0; j < L2_LEN; j++)
+ if (pt[i][j])
+ free (pt[i][j]);
+ free (pt[i]);
+ }
+ memset (pt, 0, sizeof (pt));
+ memset (mem_counters, 0, sizeof (mem_counters));
+ }
+
+ static unsigned char *
+ mem_ptr (address)
+ {
+ int pt1 = (address >> (L2_BITS + OFF_BITS)) & ((1 << L1_BITS) - 1);
+ int pt2 = (address >> OFF_BITS ) & ((1 << L2_BITS) - 1);
+ int pto = address & ((1 << OFF_BITS) - 1);
+
+ if (address == 0)
+ {
+ printf("NULL pointer dereference\n");
+ exit(1);
+ }
+
+ if (pt[pt1] == 0)
+ pt[pt1] = (unsigned char **) calloc (L2_LEN, sizeof(char **));
+ if (pt[pt1][pt2] == 0)
+ {
+ pt[pt1][pt2] = (unsigned char *) malloc (OFF_LEN);
+ memset (pt[pt1][pt2], 0, OFF_LEN);
+ }
+
+ return pt[pt1][pt2] + pto;
+ }
+
+ static void
+ used (int rstart, int i, int j)
+ {
+ int rend = i << (L2_BITS + OFF_BITS);
+ rend += j << OFF_BITS;
+ if (rstart == 0xe0000 && rend == 0xe1000)
+ return;
+ printf("mem: %08x - %08x (%dk bytes)\n", rstart, rend-1, (rend-rstart)/1024);
+ }
+
+ static char *
+ mcs(int isput, int bytes)
+ {
+ return comma(mem_counters[isput][bytes]);
+ }
+
+ void
+ mem_usage_stats ()
+ {
+ int i, j;
+ int rstart=0;
+ int pending = 0;
+
+ for (i = 0; i < L1_LEN; i++)
+ if (pt[i])
+ {
+ for (j = 0; j < L2_LEN; j++)
+ if (pt[i][j])
+ {
+ if (!pending)
+ {
+ pending = 1;
+ rstart = (i << (L2_BITS + OFF_BITS)) + (j << OFF_BITS);
+ }
+ }
+ else if (pending)
+ {
+ pending = 0;
+ used(rstart, i, j);
+ }
+ }
+ else
+ {
+ if (pending)
+ {
+ pending = 0;
+ used(rstart, i, 0);
+ }
+ }
+ /* mem foo: 123456789012 123456789012 123456789012 123456789012 123456789012 */
+ printf(" byte short pointer long fetch\n");
+ printf("mem get: %12s %12s %12s %12s %12s\n",
+ mcs (0, 1), mcs (0, 2), mcs (0, 3), mcs (0, 4), mcs (0, 0));
+ printf("mem put: %12s %12s %12s %12s\n",
+ mcs (1, 1), mcs (1, 2), mcs (1, 3), mcs (1, 4));
+ }
+
+ static int tpr = 0;
+ static void
+ s (int address, char *dir)
+ {
+ if (tpr == 0)
+ printf("MEM[%0*x] %s", membus_mask == 0xfffff ? 5 : 6, address, dir);
+ tpr++;
+ }
+ #define S(d) if (trace) s(address, d)
+ static void
+ e()
+ {
+ if (!trace)
+ return;
+ tpr--;
+ if (tpr == 0)
+ printf("\n");
+ }
+ #define E() if (trace) e()
+
+ void
+ mem_put_byte (int address, unsigned char value)
+ {
+ unsigned char *m;
+ address &= membus_mask;
+ m = mem_ptr(address);
+ if (trace)
+ printf(" %02x", value);
+ *m = value;
+ switch (address)
+ {
+ case 0x00e1:
+ {
+ static int old_led = -1;
+ static char *led_on[] = {"\033[31m O ", "\033[32m O ", "\033[34m O "};
+ static char *led_off[] = {"\033[0m · ", "\033[0m · ", "\033[0m · "};
+ int i;
+ if (old_led != value)
+ {
+ fputs(" ", stdout);
+ for (i=0; i<3; i++)
+ if (value & (1<<i))
+ fputs(led_off[i], stdout);
+ else
+ fputs(led_on[i], stdout);
+ fputs("\033[0m\r", stdout);
+ fflush(stdout);
+ old_led = value;
+ }
+ }
+ break;
+
+ case 0x400:
+ m32c_syscall (value);
+ break;
+
+ case 0x401:
+ putchar (value);
+ break;
+
+ case 0x402:
+ printf ("SimTrace: %06lx %02x\n", regs.r_pc, value);
+ break;
+
+ case 0x403:
+ printf ("SimTrap: %06lx %02x\n", regs.r_pc, value);
+ abort ();
+ }
+ }
+
+ void
+ mem_put_qi (int address, unsigned char value)
+ {
+ S ("<=");
+ mem_put_byte (address, value & 0xff);
+ E ();
+ COUNT(1,1);
+ }
+
+ void
+ mem_put_hi (int address, unsigned short value)
+ {
+ S ("<=");
+ mem_put_byte (address, value & 0xff);
+ mem_put_byte (address+1, value >> 8);
+ E ();
+ COUNT(1,2);
+ }
+
+ void
+ mem_put_psi (int address, unsigned long value)
+ {
+ S ("<=");
+ mem_put_byte (address, value & 0xff);
+ mem_put_byte (address+1, (value >> 8) & 0xff);
+ mem_put_byte (address+2, value >> 16);
+ E ();
+ COUNT(1,3);
+ }
+
+ void
+ mem_put_si (int address, unsigned long value)
+ {
+ S("<=");
+ mem_put_byte (address, value & 0xff);
+ mem_put_byte (address+1, (value >> 8) & 0xff);
+ mem_put_byte (address+2, (value >> 16) & 0xff);
+ mem_put_byte (address+3, (value >> 24) & 0xff);
+ E();
+ COUNT(1,4);
+ }
+
+ void
+ mem_put_blk (int address, void *bufptr, int nbytes)
+ {
+ S("<=");
+ if (enable_counting)
+ mem_counters[1][1] += nbytes;
+ while (nbytes--)
+ mem_put_byte (address++, *(unsigned char *)bufptr++);
+ E();
+ }
+
+ unsigned char
+ mem_get_pc ()
+ {
+ unsigned char *m = mem_ptr(regs.r_pc & membus_mask);
+ COUNT(0,0);
+ return *m;
+ }
+
+ static unsigned char
+ mem_get_byte (int address)
+ {
+ unsigned char *m;
+ address &= membus_mask;
+ S("=>");
+ m = mem_ptr(address);
+ if (trace)
+ {
+ if (tpr)
+ printf(" %02x", *m);
+ else
+ {
+ S("=>");
+ printf(" %02x", *m);
+ E();
+ }
+ }
+ E();
+ return *m;
+ }
+
+ unsigned char
+ mem_get_qi (int address)
+ {
+ unsigned char rv;
+ S("=>");
+ rv = mem_get_byte (address);
+ COUNT(0,1);
+ E();
+ return rv;
+ }
+
+ unsigned short
+ mem_get_hi (int address)
+ {
+ unsigned short rv;
+ S("=>");
+ rv = mem_get_byte (address);
+ rv |= mem_get_byte (address+1) * 256;
+ COUNT(0,2);
+ E();
+ return rv;
+ }
+
+ unsigned long
+ mem_get_psi (int address)
+ {
+ unsigned long rv;
+ S("=>");
+ rv = mem_get_byte (address);
+ rv |= mem_get_byte (address+1) * 256;
+ rv |= mem_get_byte (address+2) * 65536;
+ COUNT(0,3);
+ E();
+ return rv;
+ }
+
+ unsigned long
+ mem_get_si (int address)
+ {
+ unsigned long rv;
+ S("=>");
+ rv = mem_get_byte (address);
+ rv |= mem_get_byte (address + 1) << 8;
+ rv |= mem_get_byte (address + 2) << 16;
+ rv |= mem_get_byte (address + 3) << 24;
+ COUNT(0,4);
+ E();
+ return rv;
+ }
+
+ void
+ mem_get_blk (int address, void *bufptr, int nbytes)
+ {
+ S("=>");
+ if (enable_counting)
+ mem_counters[0][1] += nbytes;
+ while (nbytes--)
+ *(char *)bufptr++ = mem_get_byte (address++);
+ E();
+ }
+
+ int
+ sign_ext(int v, int bits)
+ {
+ if (bits < 32)
+ {
+ v &= (1<<bits) - 1;
+ if (v & (1<<(bits-1)))
+ v -= (1<<bits);
+ }
+ return v;
+ }
Index: sim/m32c/mem.h
===================================================================
RCS file: sim/m32c/mem.h
diff -N sim/m32c/mem.h
*** sim/m32c/mem.h 1 Jan 1970 00:00:00 -0000
--- sim/m32c/mem.h 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,20 ----
+ void init_mem (void);
+ void mem_usage_stats (void);
+
+ void mem_put_qi (int address, unsigned char value);
+ void mem_put_hi (int address, unsigned short value);
+ void mem_put_psi (int address, unsigned long value);
+ void mem_put_si (int address, unsigned long value);
+
+ void mem_put_blk (int address, void *bufptr, int nbytes);
+
+ unsigned char mem_get_pc ();
+
+ unsigned char mem_get_qi (int address);
+ unsigned short mem_get_hi (int address);
+ unsigned long mem_get_psi (int address);
+ unsigned long mem_get_si (int address);
+
+ void mem_get_blk (int address, void *bufptr, int nbytes);
+
+ int sign_ext (int v, int bits);
Index: sim/m32c/misc.c
===================================================================
RCS file: sim/m32c/misc.c
diff -N sim/m32c/misc.c
*** sim/m32c/misc.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/misc.c 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,54 ----
+ #include <stdio.h>
+
+ #include "cpu.h"
+ #include "misc.h"
+
+ int
+ bcd2int (int bcd, int w)
+ {
+ int v=0, m=1, i;
+ for (i = 0; i < (w ? 4 : 2); i++)
+ {
+ v += (bcd % 16) * m;
+ m *= 10;
+ bcd /= 16;
+ }
+ return v;
+ }
+
+ int
+ int2bcd (int v, int w)
+ {
+ int bcd=0, m=1, i;
+ for (i = 0; i < (w ? 4 : 2); i++)
+ {
+ bcd += (v % 10) * m;
+ m *= 16;
+ v /= 10;
+ }
+ return bcd;
+ }
+
+ char *
+ comma(unsigned int u)
+ {
+ static char buf[5][20];
+ static int bi = 0;
+ int comma=0;
+ char *bp;
+
+ bi = (bi+1) % 5;
+ bp = buf[bi] + 19;
+ *--bp = 0;
+ do {
+ if (comma == 3)
+ {
+ *--bp = ',';
+ comma = 0;
+ }
+ comma ++;
+ *--bp = '0' + (u % 10);
+ u /= 10;
+ } while (u);
+ return bp;
+ }
Index: sim/m32c/misc.h
===================================================================
RCS file: sim/m32c/misc.h
diff -N sim/m32c/misc.h
*** sim/m32c/misc.h 1 Jan 1970 00:00:00 -0000
--- sim/m32c/misc.h 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,4 ----
+ int bcd2int (int bcd, int w);
+ int int2bcd (int val, int w);
+
+ char *comma (unsigned int u);
Index: sim/m32c/opc2c.c
===================================================================
RCS file: sim/m32c/opc2c.c
diff -N sim/m32c/opc2c.c
*** sim/m32c/opc2c.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/opc2c.c 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,693 ----
+ #include <stdio.h>
+ #include <string.h>
+ #include <ctype.h>
+ #include <stdlib.h>
+
+ #include "safe-fgets.h"
+
+ static int errors = 0;
+
+ #define MAX_BYTES 10
+
+ typedef struct {
+ int varyno:16;
+ int byte:8;
+ int shift:8;
+ } VaryRef;
+
+ typedef struct {
+ char nbytes;
+ char dbytes;
+ char id[MAX_BYTES*8+1];
+ unsigned char var_start[MAX_BYTES*8+1];
+ struct {
+ unsigned char decodable_mask;
+ unsigned char decodable_bits;
+ } b[MAX_BYTES];
+ char *comment;
+ int lineno;
+ int nlines;
+ char **lines;
+ struct Indirect *last_ind;
+ int semantics_label;
+ int nvaries;
+ VaryRef *vary;
+ } opcode;
+
+ int n_opcodes;
+ opcode **opcodes;
+ opcode *op;
+
+ typedef struct {
+ char *name;
+ int nlen;
+ unsigned char mask;
+ int n_patterns;
+ unsigned char *patterns;
+ } Vary;
+
+ Vary **vary = 0;
+ int n_varies = 0;
+
+ unsigned char cur_bits[MAX_BYTES+1];
+
+ char *orig_filename;
+
+ FILE *sim_log = 0;
+ #define lprintf if (sim_log) fprintf
+
+ opcode prefix_text, suffix_text;
+
+ typedef enum {
+ T_unused,
+ T_op,
+ T_indirect,
+ T_done
+ } OpType;
+
+ typedef struct Indirect {
+ OpType type;
+ union {
+ struct Indirect *ind;
+ opcode *op;
+ } u;
+ } Indirect;
+
+ Indirect indirect[256];
+
+ static int
+ next_varybits (int bits, opcode *op, int byte)
+ {
+ int mask = op->b[byte].decodable_mask;
+ int i;
+
+ for (i=0; i<8; i++)
+ if (!(mask & (1<<i)))
+ {
+ if (bits & (1<<i))
+ {
+ bits &= ~(1<<i);
+ }
+ else
+ {
+ bits |= (1<<i);
+ return bits;
+ }
+ }
+ return 0;
+ }
+
+ static int
+ valid_varybits (int bits, opcode *op, int byte)
+ {
+ if (op->nvaries)
+ {
+ int vn;
+ for (vn=0; vn<op->nvaries; vn++)
+ {
+ int found = 0;
+ int i;
+ int ob;
+
+ if (byte != op->vary[vn].byte)
+ continue;
+ Vary *v = vary[op->vary[vn].varyno];
+ ob = (bits >> op->vary[vn].shift) & v->mask;
+ lprintf(sim_log, "varybits: vary %s ob %x\n", v->name, ob);
+
+ for (i=0; i<v->n_patterns; i++)
+ if (ob == v->patterns[i])
+ {
+ lprintf(sim_log, " found at %d\n", i);
+ found = 1;
+ break;
+ }
+ if (!found)
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+ char *
+ prmb (int mask, int bits)
+ {
+ static char buf[8][30];
+ static int bn = 0;
+ char *bp;
+
+ bn = (bn+1) % 8;
+ bp = buf[bn];
+ int i;
+ for (i=0; i<8; i++)
+ {
+ int bit = 0x80 >> i;
+ if (! (mask & bit))
+ *bp++ = '-';
+ else if (bits & bit)
+ *bp++ = '1';
+ else
+ *bp++ = '0';
+ if (i % 4 == 3)
+ *bp++ = ' ';
+ }
+ *--bp = 0;
+ return buf[bn];
+ }
+
+ static int
+ op_cmp (const void *va, const void *vb)
+ {
+ const opcode *a = *(const opcode **)va;
+ const opcode *b = *(const opcode **)vb;
+
+ if (a->nbytes != b->nbytes)
+ return a->nbytes - b->nbytes;
+
+ return strcmp (a->id, b->id);
+ }
+
+ void
+ dump_lines (opcode *op, int level, Indirect *ind)
+ {
+ char *varnames[40];
+ int i, vn=0;
+
+ if (op->semantics_label)
+ {
+ printf("%*sgoto op_semantics_%d;\n", level, "", op->semantics_label);
+ return;
+ }
+
+ if (ind != op->last_ind)
+ {
+ static int labelno = 0;
+ labelno ++;
+ printf("%*sop_semantics_%d:\n", level, "", labelno);
+ op->semantics_label = labelno;
+ }
+
+ if (op->comment) {
+ level += 2;
+ printf("%*s{\n", level, "");
+ printf("%*s %s\n", level, "", op->comment);
+ }
+
+ for (i=0; i<op->nbytes*8;)
+ {
+ if (isalpha(op->id[i]))
+ {
+ int byte = i >> 3;
+ int mask = 0;
+ int shift = 0;
+ char name[33];
+ char *np = name;
+ while (op->id[i] && isalpha(op->id[i]))
+ {
+ mask = (mask << 1) | 1;
+ shift = 7 - (i & 7);
+ *np++ = op->id[i++];
+ if (op->var_start[i])
+ break;
+ }
+ *np = 0;
+ varnames[vn++] = strdup (name);
+ printf("#line %d \"%s\"\n", op->lineno, orig_filename);
+ if (mask & ~0xff)
+ {
+ fprintf (stderr, "Error: variable %s spans bytes: %s\n",
+ name, op->comment);
+ errors ++;
+ }
+ else if (shift && (mask != 0xff))
+ printf("%*s int %s AU = (op[%d] >> %d) & 0x%02x;\n",
+ level, "", name, byte, shift, mask);
+ else if (mask != 0xff)
+ printf("%*s int %s AU = op[%d] & 0x%02x;\n",
+ level, "", name, byte, mask);
+ else
+ printf("%*s int %s AU = op[%d];\n",
+ level, "", name, byte);
+ }
+ else
+ i++;
+ }
+ if (op->comment)
+ {
+ printf("%*s if (trace) {\n", level, "");
+ printf("%*s printf(\"\\033[33m%%s\\033[0m ", level, "");
+ for (i=0; i<op->nbytes; i++)
+ printf(" %%02x");
+ printf("\\n\"");
+ printf(",\n%*s \"%s\"", level, "", op->comment);
+ for (i=0; i<op->nbytes; i++)
+ {
+ if (i == 0)
+ printf(",\n%*s op[%d]", level, "", i);
+ else
+ printf(", op[%d]", i);
+ }
+ printf(");\n");
+ for (i=0; i<vn; i++)
+ printf("%*s printf(\" %s = 0x%%x%s\", %s);\n", level, "", varnames[i],
+ (i<vn-1)?",":"\\n", varnames[i]);
+ printf("%*s }\n", level, "");
+ }
+ printf("#line %d \"%s\"\n", op->lineno+1, orig_filename);
+ for (i=0; i<op->nlines; i++)
+ printf("%*s%s", level, "", op->lines[i]);
+ if (op->comment)
+ printf("%*s}\n", level, "");
+ }
+
+ void
+ store_opcode_bits (opcode *op, int byte, Indirect *ind)
+ {
+ int bits = op->b[byte].decodable_bits;
+
+ do {
+ if (!valid_varybits (bits, op, byte))
+ continue;
+
+ switch (ind[bits].type)
+ {
+ case T_unused:
+ if (byte == op->dbytes-1)
+ {
+ ind[bits].type = T_op;
+ ind[bits].u.op = op;
+ op->last_ind = ind;
+ break;
+ }
+ else
+ {
+ int i2;
+ ind[bits].type = T_indirect;
+ ind[bits].u.ind = (Indirect *)malloc (256*sizeof(Indirect));
+ for (i2=0; i2<256; i2++)
+ ind[bits].u.ind[i2].type = T_unused;
+ store_opcode_bits (op, byte+1, ind[bits].u.ind);
+ }
+ break;
+
+ case T_indirect:
+ if (byte < op->dbytes-1)
+ store_opcode_bits (op, byte+1, ind[bits].u.ind);
+ break;
+
+ case T_op:
+ break;
+
+ case T_done:
+ break;
+ }
+ } while ((bits = next_varybits (bits, op, byte)) != 0);
+ }
+
+ void
+ emit_indirect (Indirect *ind, int byte)
+ {
+ int unsup = 0;
+ int j, n, mask;
+
+ mask = 0;
+ for (j=0; j<256; j++)
+ {
+ switch (ind[j].type)
+ {
+ case T_indirect:
+ mask = 0xff;
+ break;
+ case T_op:
+ mask |= ind[j].u.op->b[byte].decodable_mask;
+ break;
+ case T_done:
+ case T_unused:
+ break;
+ }
+ }
+
+ printf("%*s GETBYTE();\n", byte*6, "");
+ printf("%*s switch (op[%d] & 0x%02x) {\n", byte*6, "", byte, mask);
+ for (j=0; j<256; j++)
+ if ((j & ~mask) == 0)
+ {
+ switch (ind[j].type)
+ {
+ case T_done:
+ break;
+ case T_unused:
+ unsup = 1;
+ break;
+ case T_op:
+ for (n = j; n < 256; n++)
+ if ((n & ~mask) == 0
+ && ind[n].type == T_op
+ && ind[n].u.op == ind[j].u.op)
+ {
+ ind[n].type = T_done;
+ printf("%*s case 0x%02x:\n", byte*6, "", n);
+ }
+ for (n=byte; n<ind[j].u.op->nbytes-1; n++)
+ printf("%*s GETBYTE();\n", byte*6, "");
+ dump_lines(ind[j].u.op, byte*6+6, ind);
+ printf("%*s break;\n", byte*6, "");
+ break;
+ case T_indirect:
+ printf("%*s case 0x%02x:\n", byte*6, "", j);
+ emit_indirect (ind[j].u.ind, byte+1);
+ printf("%*s break;\n", byte*6, "");
+ break;
+ }
+ }
+ if (unsup)
+ printf("%*s default: UNSUPPORTED(); break;\n", byte*6, "");
+ printf("%*s }\n", byte*6, "");
+ }
+
+ static char *
+ pv_dup (char *p, char *ep)
+ {
+ int n = ep - p;
+ char *rv = (char *) malloc (n + 1);
+ memcpy (rv, p, n);
+ rv[n] = 0;
+ return rv;
+ }
+
+ static unsigned char
+ str2mask (char *str, char *ep)
+ {
+ unsigned char rv = 0;
+ while (str < ep)
+ {
+ rv *= 2;
+ if (*str == '1')
+ rv += 1;
+ str ++;
+ }
+ return rv;
+ }
+
+ static void
+ process_vary (char *line)
+ {
+ char *cp, *ep;
+ Vary *v = (Vary *) malloc (sizeof (Vary));
+
+ n_varies ++;
+ if (vary)
+ vary = (Vary **) realloc (vary, n_varies * sizeof (Vary *));
+ else
+ vary = (Vary **) malloc (n_varies * sizeof (Vary *));
+ vary[n_varies-1] = v;
+
+ cp = line;
+
+ for (cp = line; isspace(*cp); cp++) ;
+ for (ep=cp; *ep && !isspace(*ep); ep++) ;
+
+ v->name = pv_dup (cp, ep);
+ v->nlen = strlen (v->name);
+ v->mask = (1 << v->nlen) - 1;
+
+ v->n_patterns = 0;
+ v->patterns = (unsigned char *) malloc (1);
+ while (1)
+ {
+ for (cp = ep; isspace(*cp); cp++) ;
+ if (! isdigit (*cp))
+ break;
+ for (ep=cp; *ep && !isspace(*ep); ep++) ;
+ v->n_patterns ++;
+ v->patterns = (unsigned char *) realloc (v->patterns, v->n_patterns);
+ v->patterns[v->n_patterns-1] = str2mask (cp, ep);
+ }
+ }
+
+ static int
+ fieldcmp (opcode *op, int bit, char *name)
+ {
+ int n = strlen (name);
+ if (memcmp (op->id + bit, name, n) == 0
+ && (!isalpha(op->id[bit+n])
+ || op->var_start[bit+n]))
+ return 1;
+ return 0;
+ }
+
+ static void
+ log_indirect (Indirect *ind, int byte)
+ {
+ int i, j;
+ char *last_c = 0;
+
+ for (i=0; i<256; i++)
+ {
+ if (ind[i].type == T_unused)
+ continue;
+
+ for (j=0; j<byte; j++)
+ fprintf(sim_log, "%s ", prmb(255, cur_bits[j]));
+ fprintf(sim_log, "%s ", prmb(255, i));
+
+ switch (ind[i].type)
+ {
+ case T_op:
+ case T_done:
+ if (last_c && (ind[i].u.op->comment == last_c))
+ fprintf(sim_log, "''\n");
+ else
+ fprintf(sim_log, "%s\n", ind[i].u.op->comment);
+ last_c = ind[i].u.op->comment;
+ break;
+ case T_unused:
+ fprintf(sim_log, "-\n");
+ break;
+ case T_indirect:
+ fprintf(sim_log, "indirect\n");
+ cur_bits[byte] = i;
+ log_indirect (ind[i].u.ind, byte+1);
+ last_c = 0;
+ break;
+ }
+ }
+ }
+
+ int
+ main(int argc, char **argv)
+ {
+ char *line;
+ FILE *in;
+ int lineno = 0;
+ int i;
+ VaryRef *vlist;
+
+ if (argc > 2 && strcmp (argv[1], "-l") == 0)
+ {
+ sim_log = fopen(argv[2], "w");
+ fprintf(stderr, "sim_log: %s\n", argv[2]);
+ argc -= 2;
+ argv += 2;
+ }
+
+ if (argc < 2)
+ {
+ fprintf(stderr, "usage: opc2c infile.opc > outfile.opc\n");
+ exit(1);
+ }
+
+ orig_filename = argv[1];
+ in = fopen (argv[1], "r");
+ if (!in)
+ {
+ fprintf(stderr, "Unable to open file %s for reading\n", argv[1]);
+ perror("The error was");
+ exit(1);
+ }
+
+ n_opcodes = 0;
+ opcodes = (opcode **)malloc(sizeof(opcode *));
+ op = &prefix_text;
+ op->lineno = 1;
+ while ((line = safe_fgets (in)) != 0)
+ {
+ lineno ++;
+ if (strncmp (line, " /* ", 5) == 0
+ && (isdigit (line[5]) || memcmp (line+5, "VARY", 4) == 0))
+ line += 2;
+ if (line[0] == '/' && line[1] == '*')
+ {
+ if (strncmp (line, "/* */", 5) == 0)
+ {
+ op = &suffix_text;
+ op->lineno = lineno;
+ }
+ else if (strncmp (line, "/* VARY ", 8) == 0)
+ process_vary (line+8);
+ else
+ {
+ char *lp;
+ int i, bit, byte;
+ int var_start = 1;
+
+ n_opcodes ++;
+ opcodes = (opcode **) realloc (opcodes, n_opcodes * sizeof (opcode *));
+ op = (opcode *) malloc (sizeof (opcode));
+ opcodes[n_opcodes - 1] = op;
+
+ op->nbytes = op->dbytes = 0;
+ memset (op->id, 0, sizeof(op->id));
+ memset (op->var_start, 0, sizeof(op->var_start));
+ for (i=0; i<MAX_BYTES; i++)
+ {
+ op->b[i].decodable_mask = 0;
+ op->b[i].decodable_bits = 0;
+ }
+ op->comment = strdup (line);
+ op->comment[strlen(op->comment)-1] = 0;
+ while (op->comment[0] && isspace (op->comment[0]))
+ op->comment ++;
+ op->lineno = lineno;
+ op->nlines = 0;
+ op->lines = 0;
+ op->last_ind = 0;
+ op->semantics_label = 0;
+ op->nvaries = 0;
+ op->vary = 0;
+
+ i = 0;
+ for (lp = line+3; *lp; lp++)
+ {
+ bit = 7 - (i & 7);
+ byte = i >> 3;
+
+ if (strncmp (lp, "*/", 2) == 0)
+ break;
+ else if ((lp[0] == ' ' && lp[1] == ' ') || (lp[0] == '\t'))
+ break;
+ else if (*lp == ' ')
+ var_start = 1;
+ else
+ {
+ if (*lp == '0' || *lp == '1')
+ {
+ op->b[byte].decodable_mask |= 1 << bit;
+ var_start = 1;
+ if (op->dbytes < byte+1)
+ op->dbytes = byte+1;
+ }
+ else if (var_start)
+ {
+ op->var_start[i] = 1;
+ var_start = 0;
+ }
+ if (*lp == '1')
+ op->b[byte].decodable_bits |= 1 << bit;
+
+ op->nbytes = byte + 1;
+ op->id[i++] = *lp;
+ }
+ }
+ }
+ }
+ else
+ {
+ op->nlines ++;
+ if (op->lines)
+ op->lines = (char **) realloc (op->lines, op->nlines * sizeof (char *));
+ else
+ op->lines = (char **) malloc (op->nlines * sizeof (char *));
+ op->lines[op->nlines-1] = strdup (line);
+ }
+ }
+
+ {
+ int i, j;
+ for (i=0; i<n_varies; i++)
+ {
+ Vary *v = vary[i];
+ lprintf(sim_log, "V[%s] %d\n", v->name, v->nlen);
+ for (j=0; j<v->n_patterns; j++)
+ lprintf(sim_log, " P %02x\n", v->patterns[j]);
+ }
+ }
+
+ for (i=n_opcodes-2; i>= 0; i--)
+ {
+ if (opcodes[i]->nlines == 0)
+ {
+ opcodes[i]->nlines = opcodes[i+1]->nlines;
+ opcodes[i]->lines = opcodes[i+1]->lines;
+ }
+ }
+
+ for (i=0; i<256; i++)
+ indirect[i].type = T_unused;
+
+ qsort (opcodes, n_opcodes, sizeof(opcodes[0]), op_cmp);
+
+ vlist = (VaryRef *) malloc (n_varies * sizeof (VaryRef));
+
+ for (i=0; i<n_opcodes; i++)
+ {
+ int j, b, v;
+
+ for (j=0; j<opcodes[i]->nbytes; j++)
+ lprintf(sim_log, "%s ", prmb(opcodes[i]->b[j].decodable_mask, opcodes[i]->b[j].decodable_bits));
+ lprintf(sim_log, " %s\n", opcodes[i]->comment);
+
+ for (j=0; j<opcodes[i]->nbytes; j++)
+ {
+ for (b=0; b<8; b++)
+ if (isalpha (opcodes[i]->id[j*8+b]))
+ for (v=0; v<n_varies; v++)
+ if (fieldcmp (opcodes[i], j*8+b,
+ vary[v]->name))
+ {
+ int nv = opcodes[i]->nvaries ++;
+ if (nv)
+ opcodes[i]->vary = (VaryRef *) realloc (opcodes[i]->vary, (nv+1) * sizeof(VaryRef));
+ else
+ opcodes[i]->vary = (VaryRef *) malloc ((nv+1) * sizeof(VaryRef));
+
+ opcodes[i]->vary[nv].varyno = v;
+ opcodes[i]->vary[nv].byte = j;
+ opcodes[i]->vary[nv].shift = 8 - b - vary[v]->nlen;
+ lprintf(sim_log, "[vary %s shift %d]\n",
+ vary[v]->name, opcodes[i]->vary[nv].shift);
+ }
+
+ }
+ }
+
+ for (i=0; i<n_opcodes; i++)
+ {
+ int i2;
+ int bytes = opcodes[i]->dbytes;
+
+ lprintf (sim_log, "\nmask:");
+ for (i2=0; i2<opcodes[i]->nbytes; i2++)
+ lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_mask);
+ lprintf(sim_log, "%*s%s\n", 13-3*opcodes[i]->nbytes, "", opcodes[i]->comment);
+
+ lprintf (sim_log, "bits:");
+ for (i2=0; i2<opcodes[i]->nbytes; i2++)
+ lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_bits);
+ lprintf(sim_log, "%*s(%s) %d byte%s\n", 13-3*opcodes[i]->nbytes, "",
+ opcodes[i]->id, bytes, bytes==1 ? "" : "s");
+
+ store_opcode_bits (opcodes[i], 0, indirect);
+ }
+
+ dump_lines (&prefix_text, 0, 0);
+
+ emit_indirect (indirect, 0);
+
+ dump_lines (&suffix_text, 0, 0);
+
+ if (sim_log)
+ log_indirect (indirect, 0);
+
+ return errors;
+ }
Index: sim/m32c/r8c.opc
===================================================================
RCS file: sim/m32c/r8c.opc
diff -N sim/m32c/r8c.opc
*** sim/m32c/r8c.opc 1 Jan 1970 00:00:00 -0000
--- sim/m32c/r8c.opc 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,1557 ----
+ #include <stdio.h> /* -*- mode: c -*- */
+ #include <stdlib.h>
+
+ #include "cpu.h"
+ #include "mem.h"
+ #include "misc.h"
+ #include "int.h"
+
+ #define AU __attribute__((unused))
+
+ #define tprintf if (trace) printf
+
+ static unsigned char
+ getbyte ()
+ {
+ int tsave = trace;
+ unsigned char b;
+
+ if (trace == 1)
+ trace = 0;
+ b = mem_get_pc ();
+ regs.r_pc ++;
+ trace = tsave;
+ return b;
+ }
+
+ #define M16C_ONLY() /* FIXME: add something here */
+
+ #define GETBYTE() (op[opi++] = getbyte())
+
+ #define UNSUPPORTED() unsupported("unsupported", orig_pc)
+ #define NOTYET() unsupported("unimplemented", orig_pc)
+
+ static void
+ unsupported (char *tag, int orig_pc)
+ {
+ int i;
+ printf("%s opcode at %08x\n", tag, orig_pc);
+ regs.r_pc = orig_pc;
+ for (i=0; i<2; i++)
+ {
+ int b = mem_get_pc();
+ printf(" %s", bits(b>>4, 4));
+ printf(" %s", bits(b, 4));
+ regs.r_pc ++;
+ }
+ printf("\n");
+ regs.r_pc = orig_pc;
+ for (i=0; i<6; i++)
+ {
+ printf(" %02x", mem_get_pc ());
+ regs.r_pc ++;
+ }
+ printf("\n");
+ exit(1);
+ }
+
+ static int
+ IMM(bw)
+ {
+ int rv = getbyte ();
+ if (bw)
+ rv = rv + 256 * getbyte();
+ if (bw == 2)
+ rv = rv + 65536 * getbyte();
+ return rv;
+ }
+
+ #define IMM4() (immm >= 8 ? 7 - immm : immm + 1)
+
+ #define UNARY_SOP \
+ dc = decode_srcdest4 (dest, w); \
+ v = sign_ext (get_src (dc), w?16:8);
+
+ #define UNARY_UOP \
+ dc = decode_srcdest4 (dest, w); \
+ v = get_src (dc);
+
+ #define BINARY_SOP \
+ sc = decode_srcdest4 (srcx, w); \
+ dc = decode_srcdest4 (dest, w); \
+ a = sign_ext (get_src (sc), w?16:8); \
+ b = sign_ext (get_src (dc), w?16:8);
+
+ #define BINARY_UOP \
+ sc = decode_srcdest4 (srcx, w); \
+ dc = decode_srcdest4 (dest, w); \
+ a = get_src (sc); \
+ b = get_src (dc);
+
+ #define carry (FLAG_C ? 1 : 0)
+
+ static void
+ cmp (int d, int s, int w)
+ {
+ int a, b, f=0;
+ int mask = w ? 0xffff : 0xff;
+ a = d - s;
+ b = sign_ext (d, w?16:8) - sign_ext (s, w?16:8);
+ tprintf ("cmp: %x - %x = %08x, %x - %x = %d\n",
+ d, s, a,
+ sign_ext(d,w?16:8), sign_ext(s,w?16:8), b);
+
+ if (b == 0)
+ f |= FLAGBIT_Z;
+ if (b & (w ? 0x8000 : 0x80))
+ f |= FLAGBIT_S;
+ if ((d & mask) >= (s & mask))
+ f |= FLAGBIT_C;
+ if (b < (w ? -32768 : -128) || b > (w ? 32767 : 127))
+ f |= FLAGBIT_O;
+
+ set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f);
+ }
+
+ static void
+ div_op (int s, int u, int x, int w)
+ {
+ srcdest sc;
+ int v, a, b;
+
+ if (s == -1)
+ s = IMM(w);
+ else
+ {
+ sc = decode_srcdest4 (s, w);
+ s = get_src (sc);
+ }
+
+ v = get_reg (w ? r2r0 : r0);
+
+ if (!u)
+ {
+ s = sign_ext (s, w ? 16 : 8);
+ v = sign_ext (v, w ? 16 : 8);
+ }
+
+ if (s == 0)
+ {
+ set_flags (FLAGBIT_O, FLAGBIT_O);
+ return;
+ }
+
+ if (u)
+ {
+ a = (unsigned int)v / (unsigned int)s;
+ b = (unsigned int)v % (unsigned int)s;
+ }
+ else
+ {
+ a = v / s;
+ b = v % s;
+ }
+ if (x)
+ {
+ if ((s > 0 && b < 0)
+ || (s < 0 && b > 0))
+ {
+ a --;
+ b += s;
+ }
+ }
+ tprintf ("%d / %d = %d rem %d\n", v, s, a, b);
+ if ((!u && (a > (w ? 32767 : 127)
+ || a < (w ? -32768 : -129)))
+ || (u && (a > (w ? 65536 : 255))))
+ set_flags (FLAGBIT_O, FLAGBIT_O);
+ else
+ set_flags (FLAGBIT_O, 0);
+
+ put_reg (w ? r0 : r0l, a);
+ put_reg (w ? r2 : r0h, b);
+ }
+
+ static void
+ rot_op (srcdest sd, int rotc, int count)
+ {
+ int mask = (sd.bytes == 2) ? 0xffff : 0xff;
+ int msb = (sd.bytes == 2) ? 0x8000 : 0x80;
+ int v = get_src (sd);
+ int c = carry, ct;
+
+ tprintf("%s %x by %d\n", rotc ? "rotc" : "rot", v, count);
+ tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
+ while (count > 0)
+ {
+ ct = (v & msb) ? 1 : 0;
+ v <<= 1;
+ v |= rotc ? c : ct;
+ v &= mask;
+ c = ct;
+ tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
+ count --;
+ }
+ while (count < 0)
+ {
+ ct = v & 1;
+ v >>= 1;
+ v |= (rotc ? c : ct) * msb;
+ c = ct;
+ tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
+ count ++;
+ }
+ put_dest (sd, v);
+ set_szc (v, sd.bytes, c);
+ }
+
+ static void
+ shift_op (srcdest sd, int arith, int count)
+ {
+ int mask = (sd.bytes == 2) ? 0xffff : 0xff;
+ int msb = (sd.bytes == 2) ? 0x8000 : 0x80;
+ int v = get_src (sd);
+ int c = 0;
+
+ if (sd.bytes == 4)
+ {
+ mask = 0xffffffffU;
+ msb = 0x80000000U;
+ }
+
+ tprintf("%s %x by %d\n", arith ? "sha" : "shl", v, count);
+ tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
+ while (count > 0)
+ {
+ c = (v & msb) ? 1 : 0;
+ v <<= 1;
+ v &= mask;
+ tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
+ count --;
+ }
+ while (count < 0)
+ {
+ c = v & 1;
+ if (arith)
+ v = (v & msb) | (v >> 1);
+ else
+ v = (v >> 1) & (msb - 1);
+ tprintf (": %s %d\n", bits(v, 8*sd.bytes), c);
+ count ++;
+ }
+ put_dest (sd, v);
+ set_szc (v, sd.bytes, c);
+ }
+
+ #define MATH_OP(dc,s,c,op,carryrel) \
+ a = get_src(dc); \
+ b = s & b2mask[dc.bytes]; \
+ v2 = a op b op c; \
+ tprintf("0x%x " #op " 0x%x " #op " 0x%x = 0x%x\n", a, b, c, v2); \
+ a = sign_ext (a, dc.bytes * 8); \
+ b = sign_ext (s, dc.bytes * 8); \
+ v = a op b op c; \
+ tprintf("%d " #op " %d " #op " %d = %d\n", a, b, c, v); \
+ set_oszc (v, dc.bytes, v2 carryrel); \
+ put_dest (dc, v2);
+
+ #define BIT_OP(field,expr) \
+ dc = decode_bit (field); \
+ b = get_bit (dc); \
+ v = expr; \
+ tprintf ("b=%d, carry=%d, %s = %d\n", b, carry, #expr, v); \
+ put_bit (dc, v);
+
+ #define BIT_OPC(field,expr) \
+ dc = decode_bit (field); \
+ b = get_bit (dc); \
+ v = expr; \
+ tprintf ("b=%d, carry=%d, %s = %d\n", b, carry, #expr, v); \
+ set_c (v);
+
+ int
+ decode_r8c()
+ {
+ unsigned char op[40];
+ int opi = 0;
+ int v, v2, a, b;
+ int orig_pc = get_reg (pc);
+ srcdest sc, dc;
+ int imm;
+
+ step_result = M32C_MAKE_STEPPED ();
+
+ tprintf("trace: decode pc = %05x\n", orig_pc);
+
+ /* VARY dst 011 100 101 110 111 */
+
+ /* 0111 011w 1111 dest ABS.size dest */
+
+ UNARY_SOP;
+ a = v<0 ? -v : v;
+ tprintf("abs(%d) = %d\n", v, a);
+ set_osz(a, w+1);
+ put_dest (dc, a);
+
+ /* 0111 011w 0110 dest ADC.size #IMM,dest */
+
+ dc = decode_srcdest4(dest, w);
+ imm = IMM(w);
+ MATH_OP (dc, imm, carry, +, > (w?0xffff:0xff));
+
+ /* 1011 000w srcx dest ADC.size src,dest */
+
+ sc = decode_srcdest4(srcx, w);
+ dc = decode_srcdest4(dest, w);
+ b = get_src (sc);
+ MATH_OP (dc, b, carry, +, > (w?0xffff:0xff));
+
+ /* 0111 011w 1110 dest ADCF.size dest */
+
+ dc = decode_srcdest4(dest, w);
+ MATH_OP (dc, 0, carry, +, > (w?0xffff:0xff));
+
+ /* 0111 011w 0100 dest ADD.size:G #imm,dest */
+
+ dc = decode_srcdest4(dest, w);
+ imm = IMM(w);
+ MATH_OP (dc, imm, 0, +, > (w?0xffff:0xff));
+
+ /* 1100 100w immm dest ADD.size:Q #IMM,dest */
+
+ dc = decode_srcdest4(dest, w);
+ imm = sign_ext (immm, 4);
+ MATH_OP (dc, imm, 0, +, > (w?0xffff:0xff));
+
+ /* 1000 0dst ADD.B:S #IMM8,dst */
+
+ imm = IMM(0);
+ dc = decode_dest3 (dst, 0);
+ MATH_OP (dc, imm, 0, +, > 0xff);
+
+ /* 1010 000w srcx dest ADD.size:G src,dest */
+
+ sc = decode_srcdest4(srcx, w);
+ dc = decode_srcdest4(dest, w);
+ b = get_src (sc);
+ MATH_OP (dc, b, 0, +, > (w?0xffff:0xff));
+
+ /* 0010 0d sr ADD.B:S src,R0L/R0H */
+
+ sc = decode_src2 (sr, 0, d);
+ dc = decode_dest1 (d, 0);
+ b = get_src (sc);
+ MATH_OP (dc, b, 0, +, > 0xff);
+
+ /* 0111 110w 1110 1011 ADD.size:G #IMM,sp */
+
+ dc = reg_sd (sp);
+ imm = sign_ext (IMM(w), w?16:8);
+ MATH_OP (dc, imm, 0, +, > 0xffff);
+
+ /* 0111 1101 1011 immm ADD.size:Q #IMM,sp */
+
+ dc = reg_sd (sp);
+ imm = sign_ext (immm, 4);
+ MATH_OP (dc, imm, 0, +, > 0xffff);
+
+ /* 1111 100w immm dest ADJNZ.size #IMM,dest,label */
+
+ UNARY_UOP;
+ imm = sign_ext(immm, 4);
+ tprintf("%x + %d = %x\n", v, imm, v+imm);
+ v += imm;
+ put_dest (dc, v);
+ a = sign_ext (IMM(0), 8);
+ if ((v & (w ? 0xffff : 0xff)) != 0)
+ {
+ tprintf("jmp: %x + 2 + %d = ", get_reg (pc), a);
+ put_reg (pc, orig_pc + 2 + a);
+ tprintf("%x\n", get_reg (pc));
+ }
+
+ /* 0111 011w 0010 dest AND.size:G #IMM,dest */
+
+ UNARY_UOP;
+ imm = IMM(w);
+ tprintf ("%x & %x = %x\n", v, imm, v & imm);
+ v &= imm;
+ set_sz (v, w+1);
+ put_dest (dc, v);
+
+ /* 1001 0dst AND.B:S #IMM8,dest */
+
+ imm = IMM(0);
+ dc = decode_dest3 (dst, 0);
+ v = get_src (dc);
+ tprintf("%x & %x = %x\n", v, imm, v & imm);
+ v &= imm;
+ set_sz (v, 1);
+ put_dest (dc, v);
+
+ /* 1001 000w srcx dest AND.size:G src.dest */
+
+ BINARY_UOP;
+ tprintf ("%x & %x = %x\n", a, b, a & b);
+ v = a & b;
+ set_sz (v, w+1);
+ put_dest (dc, v);
+
+ /* 0001 0d sr AND.B:S src,R0L/R0H */
+
+ sc = decode_src2 (sr, 0, d);
+ dc = decode_dest1 (d, 0);
+ a = get_src (sc);
+ b = get_src (dc);
+ v = a & b;
+ tprintf("%x & %x = %x\n", a, b, v);
+ set_sz (v, 1);
+ put_dest (dc, v);
+
+ /* 0111 1110 0100 srcx BAND src */
+
+ BIT_OPC (srcx, b & carry);
+
+ /* 0111 1110 1000 dest BCLR:G dest */
+
+ dc = decode_bit (dest);
+ put_bit (dc, 0);
+
+ /* 0100 0bit BCLR:S bit,base:11[SB] */
+
+ dc = decode_bit11 (bit);
+ put_bit (dc, 0);
+
+ /* 0111 1110 0010 dest BMcnd dest */
+
+ dc = decode_bit (dest);
+ if (condition_true (IMM (0)))
+ put_bit (dc, 1);
+ else
+ put_bit (dc, 0);
+
+ /* 0111 1101 1101 cond BMcnd C */
+
+ if (condition_true (cond))
+ set_c (1);
+ else
+ set_c (0);
+
+ /* 0111 1110 0101 srcx BNAND src */
+
+ BIT_OPC (srcx, !b & carry);
+
+ /* 0111 1110 0111 srcx BNOR src */
+
+ BIT_OPC (srcx, !b | carry);
+
+ /* 0111 1110 1010 dest BNOT:G dest */
+
+ BIT_OP (dest, !b);
+
+ /* 0101 0bit BNOT:S bit,base:11[SB] */
+
+ dc = decode_bit11 (bit);
+ put_bit (dc, !get_bit (dc));
+
+ /* 0111 1110 0011 srcx BNTST src */
+
+ dc = decode_bit (srcx);
+ b = get_bit (dc);
+ set_zc (!b, !b);
+
+ /* 0111 1110 1101 srcx BNXOR src */
+
+ BIT_OPC (srcx, !b ^ carry);
+
+ /* 0111 1110 0110 srcx BOR src */
+
+ BIT_OPC (srcx, b | carry);
+
+ /* 0000 0000 BRK */
+
+ /* We report the break to our caller with the PC still pointing at the
+ breakpoint instruction. */
+ put_reg (pc, orig_pc);
+ if (verbose)
+ printf("[break]\n");
+ return M32C_MAKE_HIT_BREAK ();
+
+ /* 0111 1110 1001 dest BSET:G dest */
+
+ dc = decode_bit (dest);
+ put_bit (dc, 1);
+
+ /* 0100 1bit BSET:S bit,base:11[SB] */
+
+ dc = decode_bit11 (bit);
+ put_bit (dc, 1);
+
+ /* 0111 1110 1011 srcx BTST:G src */
+
+ dc = decode_bit (srcx);
+ b = get_bit (dc);
+ set_zc (!b, b);
+
+ /* 0101 1bit BTST:S bit,base:11[SB] */
+
+ dc = decode_bit11 (bit);
+ b = get_bit (dc);
+ set_zc (!b, b);
+
+ /* 0111 1110 0000 dest BTSTC dest */
+
+ dc = decode_bit (dest);
+ b = get_bit (dc);
+ set_zc (!b, b);
+ put_bit (dc, 0);
+
+ /* 0111 1110 0001 dest BTSTS dest */
+
+ dc = decode_bit (dest);
+ b = get_bit (dc);
+ set_zc (!b, b);
+ put_bit (dc, 1);
+
+ /* 0111 1110 1100 srcx BXOR src */
+
+ BIT_OPC (srcx, b ^ carry);
+
+ /* 0111 011w 1000 dest CMP.size:G #IMM,dest */
+
+ UNARY_UOP;
+ imm = IMM(w);
+ cmp (v, imm, w);
+
+ /* 1101 000w immm dest CMP.size:Q #IMM,dest */
+
+ UNARY_UOP;
+ immm = sign_ext (immm, 4);
+ cmp (v, immm, w);
+
+ /* 1110 0dst CMP.B:S #IMM8,dest */
+
+ imm = IMM(0);
+ dc = decode_dest3 (dst, 0);
+ v = get_src (dc);
+ cmp (v, imm, 0);
+
+ /* 1100 000w srcx dest CMP.size:G src,dest */
+
+ BINARY_UOP;
+ cmp(b, a, w);
+
+ /* 0011 1d sr CMP.B:S src,R0L/R0H */
+
+ sc = decode_src2 (sr, 0, d);
+ dc = decode_dest1 (d, 0);
+ a = get_src (sc);
+ b = get_src (dc);
+ cmp (b, a, 0);
+
+ /* 0111 110w 1110 i1c s DADC,DADD,DSBB,DSUB */
+
+ /* w = width, i = immediate, c = carry, s = subtract */
+
+ int src = i ? IMM(w) : get_reg (w ? r1 : r0h);
+ int dest = get_reg (w ? r0 : r0l);
+ int res;
+
+ src = bcd2int(src, w);
+ dest = bcd2int(dest, w);
+
+ tprintf("decimal: %d %s %d", dest, s?"-":"+", src);
+ if (c)
+ tprintf(" c=%d", carry);
+
+ if (!s)
+ {
+ res = dest + src;
+ if (c)
+ res += carry;
+ c = res > (w ? 9999 : 99);
+ }
+ else
+ {
+ res = dest - src;
+ if (c)
+ res -= (1-carry);
+ c = res >= 0;
+ if (res < 0)
+ res += w ? 10000 : 100;
+ }
+
+ res = int2bcd (res, w);
+ tprintf(" = %x\n", res);
+
+ set_szc (res, w+1, c);
+
+ put_reg (w ? r0 : r0l, res);
+
+ /* 1010 1dst DEC.B dest */
+
+ dc = decode_dest3 (dst, 0);
+ v = get_src (dc);
+ tprintf("%x -- = %x\n", v, v-1);
+ v --;
+ set_sz (v, 1);
+ put_dest (dc, v);
+
+ /* 1111 d010 DEC.W dest */
+
+ v = get_reg (d ? a1 : a0);
+ tprintf("%x -- = %x\n", v, v-1);
+ v --;
+ set_sz (v, 2);
+ put_reg (d ? a1 : a0, v);
+
+ /* 0111 110w 1110 0001 DIV.size #IMM */
+
+ div_op (-1, 0, 0, w);
+
+ /* 0111 011w 1101 srcx DIV.size src */
+
+ div_op (srcx, 0, 0, w);
+
+ /* 0111 110w 1110 0000 DIVU.size #IMM */
+
+ div_op (-1, 1, 0, w);
+
+ /* 0111 011w 1100 srcx DIVU.size src */
+
+ div_op (srcx, 1, 0, w);
+
+ /* 0111 110w 1110 0011 DIVX.size #IMM */
+
+ div_op (-1, 0, 1, w);
+
+ /* 0111 011w 1001 srcx DIVX.size src */
+
+ div_op (srcx, 0, 1, w);
+
+ /* 0111 1100 1111 0010 ENTER #IMM8 */
+
+ imm = IMM(0);
+ put_reg (sp, get_reg (sp) - 2);
+ mem_put_hi (get_reg (sp), get_reg (fb));
+ put_reg (fb, get_reg (sp));
+ put_reg (sp, get_reg (sp) - imm);
+
+ /* 0111 1101 1111 0010 EXITD */
+
+ put_reg (sp, get_reg (fb));
+ put_reg (fb, mem_get_hi (get_reg (sp)));
+ put_reg (sp, get_reg (sp) + 2);
+ put_reg (pc, mem_get_psi (get_reg (sp)));
+ put_reg (sp, get_reg (sp) + 3);
+
+ /* 0111 1100 0110 dest EXTS.B dest */
+
+ dc = decode_srcdest4 (dest, 0);
+ v = sign_ext (get_src (dc), 8);
+ dc = widen_sd (dc);
+ put_dest (dc, v);
+ set_sz (v, 1);
+
+ /* 0111 1100 1111 0011 EXTS.W R0 */
+
+ v = sign_ext (get_reg (r0), 16);
+ put_reg (r2r0, v);
+ set_sz (v, 2);
+
+ /* 1110 1011 0flg 0101 FCLR dest */
+
+ set_flags (1 << flg, 0);
+
+ /* 1110 1011 0flg 0100 FSET dest */
+
+ set_flags (1 << flg, 1 << flg);
+
+ /* 1010 0dst INC.B dest */
+
+ dc = decode_dest3 (dst, 0);
+ v = get_src (dc);
+ tprintf("%x ++ = %x\n", v, v+1);
+ v ++;
+ set_sz (v, 1);
+ put_dest (dc, v);
+
+ /* 1011 d010 INC.W dest */
+
+ v = get_reg (d ? a1 : a0);
+ tprintf("%x ++ = %x\n", v, v+1);
+ v ++;
+ set_sz (v, 2);
+ put_reg (d ? a1 : a0, v);
+
+ /* 1110 1011 11vector INT #imm */
+
+ trigger_based_interrupt (vector);
+
+ /* 1111 0110 INTO */
+
+ if (FLAG_O)
+ trigger_fixed_interrupt (0xffe0);
+
+ /* 0110 1cnd Jcnd label */
+
+ v = sign_ext (IMM(0), 8);
+ if (condition_true (cnd))
+ put_reg (pc, orig_pc + 1 + v);
+
+ /* 0111 1101 1100 cond Jcnd label */
+
+ v = sign_ext (IMM(0), 8);
+ if (condition_true (cond))
+ put_reg (pc, orig_pc + 2 + v);
+
+ /* 0110 0dsp JMP.S label */
+
+ put_reg (pc, orig_pc + 2 + dsp);
+
+ /* 1111 1110 JMP.B label */
+
+ imm = sign_ext (IMM(0), 8);
+ if (imm == -1)
+ {
+ if (verbose)
+ printf("[jmp-to-self detected as exit]\n");
+ return M32C_MAKE_HIT_BREAK ();
+ }
+ put_reg (pc, orig_pc + 1 + imm);
+
+ /* 1111 0100 JMP.W label */
+
+ imm = sign_ext (IMM(1), 16);
+ put_reg (pc, orig_pc + 1 + imm);
+
+ /* 1111 1100 JMP.A label */
+
+ imm = IMM(2);
+ put_reg (pc, imm);
+
+ /* 0111 1101 0010 srcx JMPI.W src */
+
+ sc = decode_jumpdest (srcx, 1);
+ a = get_src (sc);
+ a = sign_ext (a, 16);
+ put_reg (pc, orig_pc + a);
+
+ /* 0111 1101 0000 srcx JMPI.A src */
+
+ sc = decode_jumpdest (srcx, 0);
+ a = get_src (sc);
+ put_reg (pc, a);
+
+ /* 1110 1110 JMPS #IMM8 */
+
+ M16C_ONLY();
+
+ imm = IMM(0);
+ a = 0xf0000 + mem_get_hi (0xffffe - imm * 2);
+ put_reg (pc, a);
+
+ /* 1111 0101 JSR.W label */
+
+ imm = sign_ext (IMM(1), 16);
+ put_reg (sp, get_reg (sp) - 3);
+ mem_put_psi (get_reg (sp), get_reg (pc));
+ put_reg (pc, orig_pc + imm + 1);
+
+ /* 1111 1101 JSR.A label */
+
+ imm = IMM(2);
+ put_reg (sp, get_reg (sp) - 3);
+ mem_put_psi (get_reg (sp), get_reg (pc));
+ put_reg (pc, imm);
+
+ /* 0111 1101 0011 srcx JSRI.W src */
+
+ sc = decode_jumpdest (srcx, 1);
+ a = get_src (sc);
+ a = sign_ext (a, 16);
+
+ put_reg (sp, get_reg (sp) - 3);
+ mem_put_psi (get_reg (sp), get_reg (pc));
+ put_reg (pc, orig_pc + a);
+
+ /* 0111 1101 0001 srcx JSRI.A src */
+
+ sc = decode_jumpdest (srcx, 0);
+ a = get_src (sc);
+
+ put_reg (sp, get_reg (sp) - 3);
+ mem_put_psi (get_reg (sp), get_reg (pc));
+ put_reg (pc, a);
+
+ /* 1110 1111 JSRS #IMM8 */
+
+ M16C_ONLY();
+
+ imm = IMM(0);
+ a = 0xf0000 + mem_get_hi (0xffffe - imm * 2);
+
+ put_reg (sp, get_reg (sp) - 3);
+ mem_put_psi (get_reg (sp), get_reg (pc));
+ put_reg (pc, a);
+
+ /* 1110 1011 0reg 0000 LDC #IMM16,dest */
+
+ dc = decode_cr (reg);
+ imm = IMM(1);
+ put_dest (dc, imm);
+
+ /* 0111 1010 1reg srcx LDC src,dest */
+
+ dc = decode_cr (reg);
+ sc = decode_srcdest4 (srcx,1);
+ put_dest (dc, get_src (sc));
+
+ /* 0111 1100 1111 0000 LDCTX abs16,abs20 */
+
+ NOTYET();
+
+ /* 0111 010w 1000 dest LDE.size abs20,dest */
+
+ dc = decode_srcdest4 (dest, w);
+ imm = IMM(2);
+ if (w)
+ v = mem_get_hi (imm);
+ else
+ v = mem_get_qi (imm);
+ put_dest (dc, v);
+
+ /* 0111 010w 1001 dest LDE.size dsp:20[a0], dest */
+
+ dc = decode_srcdest4 (dest, w);
+ imm = IMM(2) + get_reg (a0);
+ if (w)
+ v = mem_get_hi (imm);
+ else
+ v = mem_get_qi (imm);
+ put_dest (dc, v);
+
+ /* 0111 010w 1010 dest LDE.size [a1a0],dest */
+
+ dc = decode_srcdest4 (dest, w);
+ imm = get_reg (a1a0);
+ if (w)
+ v = mem_get_hi (imm);
+ else
+ v = mem_get_qi (imm);
+ put_dest (dc, v);
+
+ /* 0111 1101 1010 0imm LDIPL #IMM */
+
+ set_flags (0x700, imm*0x100);
+
+ /* 0111 010w 1100 dest MOV.size:G #IMM,dest */
+
+ UNARY_UOP;
+ imm = IMM(w);
+ v = imm;
+ tprintf("%x = %x\n", v, v);
+ set_sz(v, w+1);
+ put_dest (dc, v);
+
+ /* 1101 100w immm dest MOV.size:Q #IMM,dest */
+
+ UNARY_SOP;
+ v = sign_ext (immm, 4);
+ tprintf ("%x = %x\n", v, v);
+ set_sz (v, w+1);
+ put_dest (dc, v);
+
+ /* 1100 0dst MOV.B:S #IMM8,dest */
+
+ imm = IMM(0);
+ dc = decode_dest3 (dst, 0);
+ v = imm;
+ tprintf("%x = %x\n", v, v);
+ set_sz (v, 1);
+ put_dest (dc, v);
+
+ /* 1w10 d010 MOV.size:S #IMM,dest */
+
+ /* Note that for w, 0=W and 1=B unlike the usual meaning. */
+ v = IMM(1-w);
+ tprintf("%x = %x\n", v, v);
+ set_sz (v, 2-w);
+ put_reg (d ? a1 : a0, v);
+
+ /* 1011 0dst MOV.B:Z #0,dest */
+
+ dc = decode_dest3 (dst, 0);
+ v = 0;
+ set_sz (v, 1);
+ put_dest (dc, v);
+
+ /* 0111 001w srcx dest MOV.size:G src,dest */
+
+ sc = decode_srcdest4 (srcx, w);
+ dc = decode_srcdest4 (dest, w);
+ v = get_src (sc);
+ set_sz (v, w+1);
+ put_dest (dc, v);
+
+ /* 0011 0d sr MOV.B:S src,dest */
+
+ sc = decode_src2 (sr, 0, d);
+ v = get_src (sc);
+ set_sz (v, 1);
+ put_reg (d ? a1 : a0, v);
+
+ /* 0000 0s ds MOV.B:S R0L/R0H,dest */
+
+ if (ds == 0)
+ UNSUPPORTED();
+ dc = decode_src2 (ds, 0, s);
+ v = get_reg (s ? r0h : r0l);
+ set_sz (v, 1);
+ put_dest (dc, v);
+
+ /* 0000 1d sr MOV.B:S src,R0L/R0H */
+
+ sc = decode_src2 (sr, 0, d);
+ v = get_src (sc);
+ set_sz (v, 1);
+ put_reg (d ? r0h : r0l, v);
+
+ /* 0111 010w 1011 dest MOV.size:G dsp:8[SP], dest */
+
+ dc = decode_srcdest4 (dest, w);
+ imm = IMM(0);
+ a = get_reg (sp) + sign_ext (imm, 8);
+ a &= addr_mask;
+ if (w)
+ v = mem_get_hi (a);
+ else
+ v = mem_get_qi (a);
+ set_sz (v, w+1);
+ put_dest (dc, v);
+
+ /* 0111 010w 0011 srcx MOV.size:G src, disp8[SP] */
+
+ sc = decode_srcdest4 (srcx, w);
+ imm = IMM(0);
+ a = get_reg (sp) + sign_ext (imm, 8);
+ a &= addr_mask;
+ v = get_src (sc);
+ if (w)
+ mem_put_hi (a, v);
+ else
+ mem_put_qi (a, v);
+ set_sz (v, w+1);
+
+ /* 1110 1011 0reg 1src MOVA src,dest */
+
+ static reg_id map[] = { r0, r1, r2, r3, a0, a1, 0, 0 };
+ sc = decode_srcdest4 (8 + src, 0);
+ put_reg (map[reg], sc.u.addr);
+
+ /* 0111 1100 10hl dest MOVdir R0L,dest */
+
+ if (dest == 0 || dest == 4 || dest == 5)
+ UNSUPPORTED();
+ dc = decode_srcdest4 (dest, 0);
+ a = get_src (dc);
+ b = get_reg (r0l);
+ switch (hl)
+ {
+ case 0: a = (a & 0xf0) | (b & 0x0f); break;
+ case 1: a = (a & 0xf0) | ((b>>4) & 0x0f); break;
+ case 2: a = (a & 0x0f) | ((b & 0x0f)<<4); break;
+ case 3: a = (a & 0x0f) | (b & 0xf0); break;
+ }
+ put_dest (dc, a);
+
+ /* 0111 1100 00hl srcx MOVdir src,R0L */
+
+ if (srcx == 0 || srcx == 4 || srcx == 5)
+ UNSUPPORTED();
+ sc = decode_srcdest4 (srcx, 0);
+ a = get_reg (r0l);
+ b = get_src (sc);
+ switch (hl)
+ {
+ case 0: a = (a & 0xf0) | (b & 0x0f); break;
+ case 1: a = (a & 0xf0) | ((b>>4) & 0x0f); break;
+ case 2: a = (a & 0x0f) | ((b & 0x0f)<<4); break;
+ case 3: a = (a & 0x0f) | (b & 0xf0); break;
+ }
+ put_reg (r0l, a);
+
+ /* 0111 110w 0101 dest MUL.size #IMM,dest */
+
+ UNARY_SOP;
+ imm = sign_ext (IMM(w), w?16:8);
+ tprintf("%d * %d = %d\n", v, imm, v*imm);
+ v *= imm;
+ dc = widen_sd (dc);
+ put_dest (dc, v);
+
+ /* 0111 100w srcx dest MUL.size src,dest */
+
+ BINARY_SOP;
+ v = a * b;
+ tprintf("%d * %d = %d\n", a, b, v);
+ dc = widen_sd (dc);
+ put_dest (dc, v);
+
+ /* 0111 110w 0100 dest MULU.size #IMM,dest */
+
+ UNARY_UOP;
+ imm = IMM(w);
+ tprintf("%u * %u = %u\n", v, imm, v*imm);
+ v *= imm;
+ dc = widen_sd (dc);
+ put_dest (dc, v);
+
+ /* 0111 000w srcx dest MULU.size src,dest */
+
+ BINARY_UOP;
+ v = a * b;
+ tprintf("%u * %u = %u\n", a, b, v);
+ dc = widen_sd (dc);
+ put_dest (dc, v);
+
+ /* 0111 010w 0101 dest NEG.size dest */
+
+ UNARY_SOP;
+ tprintf("%d * -1 = %d\n", v, -v);
+ v = -v;
+ set_oszc (v, w+1, v == 0);
+ put_dest (dc, v);
+
+ /* 0000 0100 NOP */
+
+ tprintf("nop\n");
+
+ /* 0111 010w 0111 dest NOT.size:G */
+
+ UNARY_UOP;
+ tprintf("~ %x = %x\n", v, ~v);
+ v = ~v;
+ set_sz (v, w+1);
+ put_dest (dc, v);
+
+ /* 1011 1dst NOT.B:S dest */
+
+ dc = decode_dest3 (dst, 0);
+ v = get_src (dc);
+ tprintf("~ %x = %x\n", v, ~v);
+ v = ~v;
+ set_sz (v, 1);
+ put_dest (dc, v);
+
+ /* 0111 011w 0011 dest OR.size:G #IMM,dest */
+
+ UNARY_UOP;
+ imm = IMM(w);
+ tprintf ("%x | %x = %x\n", v, imm, v | imm);
+ v |= imm;
+ set_sz (v, w+1);
+ put_dest (dc, v);
+
+ /* 1001 1dst OR.B:S #IMM8,dest */
+
+ imm = IMM(0);
+ dc = decode_dest3 (dst, 0);
+ v = get_src (dc);
+ tprintf("%x | %x = %x\n", v, imm, v|imm);
+ v |= imm;
+ set_sz (v, 1);
+ put_dest (dc, v);
+
+ /* 1001 100w srcx dest OR.size:G src,dest */
+
+ BINARY_UOP;
+ tprintf ("%x | %x = %x\n", a, b, a | b);
+ v = a | b;
+ set_sz (v, w+1);
+ put_dest (dc, v);
+
+ /* 0001 1d sr OR.B:S src,R0L/R0H */
+
+ sc = decode_src2 (sr, 0, d);
+ dc = decode_dest1 (d, 0);
+ a = get_src (sc);
+ b = get_src (dc);
+ v = a | b;
+ tprintf("%x | %x = %x\n", a, b, v);
+ set_sz (v, 1);
+ put_dest (dc, v);
+
+ /* 0111 010w 1101 dest POP.size:G dest */
+
+ dc = decode_srcdest4 (dest, w);
+ if (w)
+ {
+ v = mem_get_hi (get_reg (sp));
+ put_reg (sp, get_reg (sp) + 2);
+ tprintf("pophi: %x\n", v);
+ }
+ else
+ {
+ v = mem_get_qi (get_reg (sp));
+ put_reg (sp, get_reg (sp) + 1);
+ tprintf("popqi: %x\n", v);
+ }
+ put_dest (dc, v);
+
+ /* 1001 d010 POP.B:S dest */
+
+ v = mem_get_qi (get_reg (sp));
+ put_reg (d ? r0h : r0l, v);
+ put_reg (sp, get_reg (sp) + 1);
+ tprintf("popqi: %x\n", v);
+
+ /* 1101 d010 POP.W:S dest */
+
+ v = mem_get_hi (get_reg (sp));
+ put_reg (d ? a1 : a0, v);
+ put_reg (sp, get_reg (sp) + 2);
+ tprintf("pophi: %x\n", v);
+
+ /* 1110 1011 0reg 0011 POPC dest */
+
+ dc = decode_cr (reg);
+ v = mem_get_hi (get_reg (sp));
+ put_dest (dc, v);
+ put_reg (sp, get_reg (sp) + 2);
+ tprintf("popc: %x\n", v);
+
+ /* 1110 1101 POPM dest */
+
+ static int map[] = { r0, r1, r2, r3, a0, a1, sb, fb };
+ imm = IMM(0);
+ tprintf("popm: %x\n", imm);
+ for (a=0; a<8; a++)
+ if (imm & (1<<a))
+ {
+ v = mem_get_hi (get_reg (sp));
+ put_reg (map[a], v);
+ put_reg (sp, get_reg (sp) + 2);
+ }
+
+ /* 0111 110w 1110 0010 PUSH.size:G #IMM */
+
+ imm = IMM(w);
+ if (w)
+ {
+ put_reg (sp, get_reg (sp) - 2);
+ mem_put_hi (get_reg (sp), imm);
+ tprintf("pushhi %04x\n", imm);
+ }
+ else
+ {
+ put_reg (sp, get_reg (sp) - 1);
+ mem_put_qi (get_reg (sp), imm);
+ tprintf("pushqi %02x\n", imm);
+ }
+
+ /* 0111 010w 0100 srcx PUSH.size:G src */
+
+ sc = decode_srcdest4 (srcx, w);
+ v = get_src (sc);
+ if (w)
+ {
+ put_reg (sp, get_reg (sp) - 2);
+ mem_put_hi (get_reg (sp), v);
+ tprintf("pushhi: %x\n", v);
+ }
+ else
+ {
+ put_reg (sp, get_reg (sp) - 1);
+ mem_put_qi (get_reg (sp), v);
+ tprintf("pushqi: %x\n", v);
+ }
+
+ /* 1000 s010 PUSH.B:S src */
+
+ v = get_reg (s ? r0h : r0l);
+ put_reg (sp, get_reg (sp) - 1);
+ mem_put_qi (get_reg (sp), v);
+ tprintf("pushqi: %x\n", v);
+
+ /* 1100 s010 PUSH.W:S src */
+
+ v = get_reg (s ? a1 : a0);
+ put_reg (sp, get_reg (sp) - 2);
+ mem_put_hi (get_reg (sp), v);
+ tprintf("pushhi: %x\n", v);
+
+ /* 0111 1101 1001 srcx PUSHA src */
+
+ sc = decode_srcdest4 (srcx, 0);
+ put_reg (sp, get_reg (sp) - 2);
+ mem_put_hi (get_reg (sp), sc.u.addr);
+ tprintf("pushhi: %x\n", sc.u.addr);
+
+ /* 1110 1011 0src 0010 PUSHC src */
+
+ sc = decode_cr (src);
+ put_reg (sp, get_reg (sp) - 2);
+ v = get_src (sc);
+ mem_put_hi (get_reg (sp), v);
+ tprintf("pushc: %x\n", v);
+
+ /* 1110 1100 PUSHM src */
+
+ static int map[] = { fb, sb, a1, a0, r3, r2, r1, r0 };
+ imm = IMM(0);
+ tprintf("pushm: %x\n", imm);
+ for (a=0; a<8; a++)
+ if (imm & (1<<a))
+ {
+ put_reg (sp, get_reg (sp) - 2);
+ v = get_reg (map[a]);
+ mem_put_hi (get_reg (sp), v);
+ }
+
+ /* 1111 1011 REIT */
+
+ a = get_reg (sp);
+ v = (mem_get_hi (a)
+ + 65536 * (mem_get_qi (a+3) & 0x0f));
+ b = (mem_get_qi (a+2)
+ + 16 * (mem_get_qi (a+3) & 0xf0));
+ put_reg (pc, v);
+ put_reg (flags, b);
+ put_reg (sp, get_reg (sp) + 4);
+
+ /* 0111 110w 1111 0001 RMPA.size */
+
+ int count = get_reg (r3);
+ int list1 = get_reg (a0);
+ int list2 = get_reg (a1);
+ int sum = get_reg (w ? r2r0 : r0);
+
+ while (count)
+ {
+ if (w)
+ {
+ a = sign_ext (mem_get_hi (list1), 16);
+ b = sign_ext (mem_get_hi (list2), 16);
+ }
+ else
+ {
+ a = sign_ext (mem_get_qi (list1), 8);
+ b = sign_ext (mem_get_qi (list2), 8);
+ }
+ tprintf("%d + %d * %d = ", sum, a, b);
+ sum += a * b;
+ tprintf("%d\n", sum);
+ list1 += w ? 2 : 1;
+ list2 += w ? 2 : 1;
+ count --;
+ }
+ put_reg (r3, count);
+ put_reg (a0, list1);
+ put_reg (a1, list2);
+ put_reg (w ? r2r0 : r0, sum);
+
+ /* 0111 011w 1010 dest ROLC.size dest */
+
+ dc = decode_srcdest4 (dest, w);
+ rot_op (dc, 1, 1);
+
+ /* 0111 011w 1011 dest RORC.size dest */
+
+ dc = decode_srcdest4 (dest, w);
+ rot_op (dc, 1, -1);
+
+ /* 1110 000w immm dest ROT.size #IMM,dest */
+
+ dc = decode_srcdest4 (dest, w);
+ rot_op (dc, 0, IMM4());
+
+ /* 0111 010w 0110 dest ROT.size R1H,dest */
+
+ dc = decode_srcdest4 (dest, w);
+ rot_op (dc, 0, sign_ext (get_reg (r1h), 8));
+
+ /* 1111 0011 RTS */
+
+ put_reg (pc, mem_get_psi (get_reg (sp)));
+ put_reg (sp, get_reg (sp) + 3);
+
+ /* 0111 011w 0111 dest SBB.size #IMM,dest */
+
+ dc = decode_srcdest4 (dest, w);
+ imm = IMM(w);
+ MATH_OP (dc, imm, !carry, -, >= 0);
+
+ /* 1011 100w srcx dest SBB.size src,dest */
+
+ sc = decode_srcdest4(srcx, w);
+ dc = decode_srcdest4(dest, w);
+ b = get_src (sc);
+ MATH_OP (dc, b, !carry, -, >= 0);
+
+ /* 1111 000w immm dest SHA.size #IMM, dest */
+
+ dc = decode_srcdest4(dest, w);
+ shift_op (dc, 1, IMM4());
+
+ /* 0111 010w 1111 dest SHA.size R1H,dest */
+
+ dc = decode_srcdest4(dest, w);
+ a = sign_ext (get_reg (r1h), 8);
+ shift_op (dc, 1, a);
+
+ /* 1110 1011 101d immm SHA.L #IMM, dest */
+
+ dc = reg_sd (d ? r3r1 : r2r0);
+ shift_op (dc, 1, IMM4());
+
+ /* 1110 1011 001d 0001 SHA.L R1H,dest */
+
+ dc = reg_sd (d ? r3r1 : r2r0);
+ a = sign_ext (get_reg (r1h), 8);
+ shift_op (dc, 1, a);
+
+ /* 1110 100w immm dest SHL.size #IMM, dest */
+
+ dc = decode_srcdest4(dest, w);
+ shift_op (dc, 0, IMM4());
+
+ /* 0111 010w 1110 dest SHL.size R1H,dest */
+
+ dc = decode_srcdest4(dest, w);
+ a = sign_ext (get_reg (r1h), 8);
+ shift_op (dc, 0, a);
+
+ /* 1110 1011 100d immm SHL.L #IMM,dest */
+
+ dc = reg_sd (d ? r3r1 : r2r0);
+ shift_op (dc, 0, IMM4());
+
+ /* 1110 1011 000d 0001 SHL.L R1H,dest */
+
+ dc = reg_sd (d ? r3r1 : r2r0);
+ a = sign_ext (get_reg (r1h), 8);
+ shift_op (dc, 0, a);
+
+ /* 0111 110w 1110 100b SMOVB.size */
+
+ int count = get_reg (r3);
+ int s1 = get_reg (a0) + (get_reg (r1h) << 16);
+ int s2 = get_reg (a1);
+ int inc = (w ? 2 : 1) * (b ? -1 : 1);
+
+ while (count)
+ {
+ if (w)
+ {
+ v = mem_get_hi (s1);
+ mem_put_hi (s2, v);
+ }
+ else
+ {
+ v = mem_get_qi (s1);
+ mem_put_qi (s2, v);
+ }
+ s1 += inc;
+ s2 += inc;
+ count --;
+ }
+ put_reg (r3, count);
+ put_reg (a0, s1 & 0xffff);
+ put_reg (a1, s2);
+ put_reg (r1h, s1 >> 16);
+
+ /* 0111 110w 1110 1010 SSTR.size */
+
+ int count = get_reg (r3);
+ int s1 = get_reg (a1);
+ v = get_reg (w ? r0 : r0h);
+
+ while (count)
+ {
+ if (w)
+ {
+ mem_put_hi (s1, v);
+ s1 += 2;
+ }
+ else
+ {
+ mem_put_qi (s1, v);
+ s1 += 1;
+ }
+ count --;
+ }
+ put_reg (r3, count);
+ put_reg (a1, s1);
+
+ /* 0111 1011 1src dest STC src,dest */
+
+ dc = decode_srcdest4 (dest, 1);
+ sc = decode_cr (src);
+ put_dest (dc, get_src(sc));
+
+ /* 0111 1100 1100 dest STC PC,dest */
+
+ dc = decode_srcdest4 (dest, 1);
+ dc.bytes = 3;
+ put_dest (dc, orig_pc);
+
+ /* 0111 1101 1111 0000 STCTX abs16,abs20 */
+
+ NOTYET();
+
+ /* 0111 010w 0000 srcx STE.size src,abs20 */
+
+ sc = decode_srcdest4 (srcx, w);
+ a = IMM(2);
+ v = get_src (sc);
+ if (w)
+ mem_put_hi (a, v);
+ else
+ mem_put_qi (a, v);
+ if (srcx == 4 || srcx == 5)
+ {
+ v = get_reg (sc.u.reg);
+ set_sz (v, 2);
+ }
+ else
+ set_sz (v, w+1);
+
+ /* 0111 010w 0001 srcx STE.size src,disp20[a0] */
+
+ sc = decode_srcdest4 (srcx, w);
+ a = get_reg(a0) + IMM(2);
+ v = get_src (sc);
+ if (w)
+ mem_put_hi (a, v);
+ else
+ mem_put_qi (a, v);
+ if (srcx == 4 || srcx == 5)
+ {
+ v = get_reg (sc.u.reg);
+ set_sz (v, 2);
+ }
+ else
+ set_sz (v, w+1);
+
+ /* 0111 010w 0010 srcx STE.size src,[a1a0] */
+
+ sc = decode_srcdest4 (srcx, w);
+ a = get_reg(a1a0);
+ v = get_src (sc);
+ if (w)
+ mem_put_hi (a, v);
+ else
+ mem_put_qi (a, v);
+ if (srcx == 4 || srcx == 5)
+ {
+ v = get_reg (sc.u.reg);
+ set_sz (v, 2);
+ }
+ else
+ set_sz (v, w+1);
+
+ /* 1101 0dst STNZ #IMM8,dest */
+
+ imm = IMM(0);
+ dc = decode_dest3(dst, 0);
+ if (!FLAG_Z)
+ put_dest (dc, imm);
+
+ /* 1100 1dst STZ #IMM8,dest */
+
+ imm = IMM(0);
+ dc = decode_dest3(dst, 0);
+ if (FLAG_Z)
+ put_dest (dc, imm);
+
+ /* 1101 1dst STZX #IMM81,#IMM82,dest */
+
+ a = IMM(0);
+ dc = decode_dest3(dst, 0);
+ b = IMM(0);
+ if (FLAG_Z)
+ put_dest (dc, a);
+ else
+ put_dest (dc, b);
+
+ /* 0111 011w 0101 dest SUB.size:G #IMM,dest */
+
+ dc = decode_srcdest4 (dest, w);
+ imm = IMM(w);
+ MATH_OP (dc, imm, 0, -, >= 0);
+
+ /* 1000 1dst SUB.B:S #IMM8,dest */
+
+ imm = IMM(0);
+ dc = decode_dest3 (dst, 0);
+ MATH_OP (dc, imm, 0, -, >= 0);
+
+ /* 1010 100w srcx dest SUB.size:G src,dest */
+
+ sc = decode_srcdest4(srcx, w);
+ dc = decode_srcdest4(dest, w);
+ b = get_src (sc);
+ MATH_OP (dc, b, 0, -, > 0);
+
+ /* 0010 1d sr SUB.B:S src,R0L/R0H */
+
+ sc = decode_src2 (sr, 0, d);
+ dc = decode_dest1 (d, 0);
+ b = get_src (sc);
+ MATH_OP (dc, b, 0, -, > 0);
+
+ /* 0111 011w 0000 dest TST.size #IMM, dest */
+
+ UNARY_UOP;
+ imm = IMM(w);
+ tprintf ("%x & %x = %x\n", v, imm, v & imm);
+ v &= imm;
+ set_sz (v, w+1);
+
+ /* 1000 000w srcx dest TST.size src,dest */
+
+ BINARY_UOP;
+ tprintf ("%x & %x = %x\n", a, b, a & b);
+ v = a & b;
+ set_sz (v, w+1);
+
+ /* 1111 1111 UND */
+
+ trigger_fixed_interrupt (0xffdc);
+
+ /* 0111 1101 1111 0011 WAIT */
+
+ tprintf("waiting...\n");
+
+ /* 0111 101w 00sr dest XCHG.size src,dest */
+
+ sc = decode_srcdest4 (sr, w);
+ dc = decode_srcdest4 (dest, w);
+ a = get_src (sc);
+ b = get_src (dc);
+ put_dest (dc, a);
+ put_dest (sc, b);
+
+ /* 0111 011w 0001 dest XOR.size #IMM,dest */
+
+ UNARY_UOP;
+ imm = IMM(w);
+ tprintf ("%x ^ %x = %x\n", v, imm, v ^ imm);
+ v ^= imm;
+ set_sz (v, w+1);
+ put_dest (dc, v);
+
+ /* 1000 100w srcx dest XOR.size src,dest */
+
+ BINARY_UOP;
+ tprintf ("%x ^ %x = %x\n", a, b, a ^ b);
+ v = a ^ b;
+ set_sz (v, w+1);
+ put_dest (dc, v);
+
+ /* OP */
+ /* */
+
+ return step_result;
+ }
Index: sim/m32c/reg.c
===================================================================
RCS file: sim/m32c/reg.c
diff -N sim/m32c/reg.c
*** sim/m32c/reg.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/reg.c 6 Oct 2005 22:36:52 -0000
***************
*** 0 ****
--- 1,542 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+
+ #include "cpu.h"
+
+ int verbose = 0;
+ int trace = 0;
+ int enable_counting = 0;
+
+ regs_type regs;
+ int addr_mask = 0xffff;
+ int membus_mask = 0xfffff;
+ int m32c_cpu = 0;
+ int step_result;
+ unsigned int heapbottom = 0;
+ unsigned int heaptop = 0;
+
+ char *reg_names[] = {
+ "mem",
+ "r0", "r0h", "r0l",
+ "r1", "r1h", "r1l",
+ "r2", "r2r0",
+ "r3", "r3r1",
+ "r3r1r2r0",
+ "r3r2r1r0",
+ "a0",
+ "a1", "a1a0",
+ "sb", "fb",
+ "intb", "intbl", "intbh",
+ "sp", "usp", "isp", "pc", "flags"
+ };
+
+ int reg_bytes[] = {
+ 0,
+ 2, 1, 1,
+ 2, 1, 1,
+ 2, 4,
+ 2, 4,
+ 8,
+ 8,
+ 2,
+ 2, 4,
+ 2, 2,
+ 2, 1, 3,
+ 2, 2, 2, 3, 2
+ };
+
+
+ unsigned int b2mask[] = { 0, 0xff, 0xffff, 0xffffff, 0xffffffff };
+ unsigned int b2signbit[] = { 0, (1<<7), (1<<15), (1<<24), (1<<31) };
+ int b2maxsigned[] = { 0, 0x7f, 0x7fff, 0x7fffff, 0x7fffffff };
+ int b2minsigned[] = { 0, -128, -32768, -8388608, -2147483647-1 };
+
+ static regs_type oldregs;
+
+ void
+ init_regs (void)
+ {
+ memset (®s, 0, sizeof (regs));
+ memset (&oldregs, 0, sizeof (oldregs));
+ }
+
+ void
+ set_pointer_width (int bytes)
+ {
+ if (bytes == 2)
+ {
+ addr_mask = 0xffff;
+ membus_mask = 0x000fffff;
+ reg_bytes[a0] = reg_bytes[a1] = reg_bytes[sb] = reg_bytes[fb] =
+ reg_bytes[sp] = reg_bytes[usp] = reg_bytes[isp] = 2;
+ }
+ else
+ {
+ addr_mask = 0xffffff;
+ membus_mask = 0x00ffffff;
+ reg_bytes[a0] = reg_bytes[a1] = reg_bytes[sb] = reg_bytes[fb] =
+ reg_bytes[sp] = reg_bytes[usp] = reg_bytes[isp] = 3;
+ }
+ }
+
+ void
+ m32c_set_cpu (int cpu)
+ {
+ switch (cpu)
+ {
+ case CPU_R8C:
+ case CPU_M16C:
+ set_pointer_width (2);
+ decode_opcode = decode_r8c;
+ break;
+ case CPU_M32CM:
+ case CPU_M32C:
+ set_pointer_width (3);
+ decode_opcode = decode_m32c;
+ break;
+ default:
+ abort();
+ }
+ m32c_cpu = cpu;
+ }
+
+ static unsigned int
+ get_reg_i (reg_id id)
+ {
+ reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
+
+ switch (id)
+ {
+ case r0:
+ return b->r_r0;
+ case r0h:
+ return b->r_r0 >> 8;
+ case r0l:
+ return b->r_r0 & 0xff;
+ case r1:
+ return b->r_r1;
+ case r1h:
+ return b->r_r1 >> 8;
+ case r1l:
+ return b->r_r1 & 0xff;
+ case r2:
+ return b->r_r2;
+ case r2r0:
+ return b->r_r2 * 65536 + b->r_r0;
+ case r3:
+ return b->r_r3;
+ case r3r1:
+ return b->r_r3 * 65536 + b->r_r1;
+
+ case a0:
+ return b->r_a0 & addr_mask;
+ case a1:
+ return b->r_a1 & addr_mask;
+ case a1a0:
+ return (b->r_a1 & 0xffff) * 65536 | (b->r_a0 & 0xffff);
+
+ case sb:
+ return b->r_sb & addr_mask;
+ case fb:
+ return b->r_fb & addr_mask;
+
+ case intb:
+ return regs.r_intbh * 65536 + regs.r_intbl;
+ case intbl:
+ return regs.r_intbl;
+ case intbh:
+ return regs.r_intbh;
+
+ case sp:
+ return ((regs.r_flags & FLAGBIT_U) ? regs.r_usp : regs.r_isp) & addr_mask;
+ case usp:
+ return regs.r_usp & addr_mask;
+ case isp:
+ return regs.r_isp & addr_mask;
+
+ case pc:
+ return regs.r_pc & membus_mask;
+ case flags:
+ return regs.r_flags;
+ default:
+ abort();
+ }
+ }
+
+ unsigned int
+ get_reg (reg_id id)
+ {
+ unsigned int rv = get_reg_i (id);
+ if (trace > ((id != pc && id != fb && id != sp) ? 0 : 1))
+ printf("get_reg (%s) = %0*x\n", reg_names[id], reg_bytes[id]*2, rv);
+ return rv;
+ }
+
+ DI
+ get_reg_ll (reg_id id)
+ {
+ reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
+
+ switch (id)
+ {
+ case r3r1r2r0:
+ return ((DI)b->r_r3 << 48
+ | (DI)b->r_r1 << 32
+ | (DI)b->r_r2 << 16
+ | (DI)b->r_r0);
+ case r3r2r1r0:
+ return ((DI)b->r_r3 << 48
+ | (DI)b->r_r2 << 32
+ | (DI)b->r_r1 << 16
+ | (DI)b->r_r0);
+ default:
+ return get_reg (id);
+ }
+ }
+
+ static int highest_sp=0, lowest_sp=0xffffff;
+
+ void
+ stack_heap_stats ()
+ {
+ printf("heap: %08x - %08x (%d bytes)\n", heapbottom, heaptop, heaptop-heapbottom);
+ printf("stack: %08x - %08x (%d bytes)\n", lowest_sp, highest_sp, highest_sp - lowest_sp);
+ }
+
+ void
+ put_reg (reg_id id, unsigned int v)
+ {
+ if (trace > ((id != pc) ? 0 : 1))
+ printf("put_reg (%s) = %0*x\n", reg_names[id], reg_bytes[id]*2, v);
+
+ reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
+ switch (id)
+ {
+ case r0:
+ b->r_r0 = v;
+ break;
+ case r0h:
+ b->r_r0 = (b->r_r0 & 0xff) | (v << 8);
+ break;
+ case r0l:
+ b->r_r0 = (b->r_r0 & 0xff00) | (v & 0xff);
+ break;
+ case r1:
+ b->r_r1 = v;
+ break;
+ case r1h:
+ b->r_r1 = (b->r_r1 & 0xff) | (v << 8);
+ break;
+ case r1l:
+ b->r_r1 = (b->r_r1 & 0xff00) | (v & 0xff);
+ break;
+ case r2:
+ b->r_r2 = v;
+ break;
+ case r2r0:
+ b->r_r0 = v & 0xffff;
+ b->r_r2 = v >> 16;
+ break;
+ case r3:
+ b->r_r3 = v;
+ break;
+ case r3r1:
+ b->r_r1 = v & 0xffff;
+ b->r_r3 = v >> 16;
+ break;
+
+ case a0:
+ b->r_a0 = v & addr_mask;
+ break;
+ case a1:
+ b->r_a1 = v & addr_mask;
+ break;
+ case a1a0:
+ b->r_a0 = v & 0xffff;
+ b->r_a1 = v >> 16;
+ break;
+
+ case sb:
+ b->r_sb = v & addr_mask;
+ break;
+ case fb:
+ b->r_fb = v & addr_mask;
+ break;
+
+ case intb:
+ regs.r_intbl = v & 0xffff;
+ regs.r_intbh = v >> 16;
+ break;
+ case intbl:
+ regs.r_intbl = v & 0xffff;
+ break;
+ case intbh:
+ regs.r_intbh = v & 0xff;
+ break;
+
+ case sp:
+ {
+ SI *spp;
+ if (regs.r_flags & FLAGBIT_U)
+ spp = ®s.r_usp;
+ else
+ spp = ®s.r_isp;
+ *spp = v & addr_mask;
+ if (*spp < heaptop)
+ {
+ printf("collision: pc %08lx heap %08x stack %08lx\n", regs.r_pc, heaptop, *spp);
+ exit(1);
+ }
+ if (*spp < lowest_sp)
+ lowest_sp = *spp;
+ if (*spp > highest_sp)
+ highest_sp = *spp;
+ break;
+ }
+ case usp:
+ regs.r_usp = v & addr_mask;
+ break;
+ case isp:
+ regs.r_isp = v & addr_mask;
+ break;
+
+ case pc:
+ regs.r_pc = v & membus_mask;
+ break;
+ case flags:
+ regs.r_flags = v;
+ break;
+ default:
+ abort();
+ }
+ }
+
+ int
+ condition_true (int cond_id)
+ {
+ int f;
+ if (A16)
+ {
+ static const char *cond_name[] = {
+ "C", "C&!Z", "Z", "S",
+ "!C", "!(C&!Z)", "!Z", "!S",
+ "(S^O)|Z", "O", "!(S^O)", "unk",
+ "!((S^O)|Z)", "!O", "S^O", "unk"};
+ switch (cond_id)
+ {
+ case 0: f = FLAG_C; break; /* GEU/C */
+ case 1: f = FLAG_C & ! FLAG_Z; break; /* GTU */
+ case 2: f = FLAG_Z; break; /* EQ/Z*/
+ case 3: f = FLAG_S; break; /* N */
+ case 4: f = ! FLAG_C; break; /* LTU/NC */
+ case 5: f = ! (FLAG_C & !FLAG_Z); break; /* LEU */
+ case 6: f = ! FLAG_Z; break; /* NE/NZ */
+ case 7: f = ! FLAG_S; break; /* PZ */
+
+ case 8: f = (FLAG_S ^ FLAG_O) | FLAG_Z; break; /* LE */
+ case 9: f = FLAG_O; break; /* O */
+ case 10: f = !(FLAG_S ^ FLAG_O); break; /* GE */
+ case 12: f = !((FLAG_S ^ FLAG_O) | FLAG_Z); break; /* GT */
+ case 13: f = ! FLAG_O; break; /* NO */
+ case 14: f = FLAG_S ^ FLAG_O; break; /* LT */
+
+ default:
+ f = 0;
+ break;
+ }
+ if (trace)
+ printf("cond[%d] %s = %s\n", cond_id, cond_name[cond_id&15], f?"true":"false");
+ }
+ else
+ {
+ static const char *cond_name[] = {
+ "!C", "LEU", "!Z", "PZ",
+ "!O", "GT", "GE", "?",
+ "C", "GTU", "Z", "N",
+ "O", "LE", "LT", "!?"};
+ switch (cond_id)
+ {
+ case 0: f = ! FLAG_C; break; /* LTU/NC */
+ case 1: f = ! (FLAG_C & !FLAG_Z); break; /* LEU */
+ case 2: f = ! FLAG_Z; break; /* NE/NZ */
+ case 3: f = ! FLAG_S; break; /* PZ */
+
+ case 4: f = ! FLAG_O; break; /* NO */
+ case 5: f = !((FLAG_S ^ FLAG_O) | FLAG_Z); break; /* GT */
+ case 6: f = !(FLAG_S ^ FLAG_O); break; /* GE */
+
+ case 8: f = FLAG_C; break; /* GEU/C */
+ case 9: f = FLAG_C & ! FLAG_Z; break; /* GTU */
+ case 10: f = FLAG_Z; break; /* EQ/Z*/
+ case 11: f = FLAG_S; break; /* N */
+
+ case 12: f = FLAG_O; break; /* O */
+ case 13: f = (FLAG_S ^ FLAG_O) | FLAG_Z; break; /* LE */
+ case 14: f = FLAG_S ^ FLAG_O; break; /* LT */
+
+ default:
+ f = 0;
+ break;
+ }
+ if (trace)
+ printf("cond[%d] %s = %s\n", cond_id, cond_name[cond_id&15], f?"true":"false");
+ }
+ return f;
+ }
+
+ void
+ set_flags (int mask, int newbits)
+ {
+ int i;
+ regs.r_flags &= ~mask;
+ regs.r_flags |= newbits & mask;
+ if (trace)
+ {
+ printf("flags now \033[32m %d", (regs.r_flags >> (A16 ? 8 : 12))&7);
+ for (i=7; i>=0; i--)
+ if (regs.r_flags & (1<<i))
+ putchar("CDZSBOIU"[i]);
+ else
+ putchar('-');
+ printf("\033[0m\n");
+ }
+ }
+
+ void
+ set_oszc (int value, int b, int c)
+ {
+ int mask = b2mask[b];
+ int f = 0;
+
+ if (c)
+ f |= FLAGBIT_C;
+ if ((value & mask) == 0)
+ f |= FLAGBIT_Z;
+ if (value & b2signbit[b])
+ f |= FLAGBIT_S;
+ if ((value > b2maxsigned[b])
+ || (value < b2minsigned[b]))
+ f |= FLAGBIT_O;
+ set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f);
+ }
+
+ void
+ set_szc (int value, int b, int c)
+ {
+ int mask = b2mask[b];
+ int f = 0;
+
+ if (c)
+ f |= FLAGBIT_C;
+ if ((value & mask) == 0)
+ f |= FLAGBIT_Z;
+ if (value & b2signbit[b])
+ f |= FLAGBIT_S;
+ set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_C, f);
+ }
+
+ void
+ set_osz (int value, int b)
+ {
+ int mask = b2mask[b];
+ int f = 0;
+
+ if ((value & mask) == 0)
+ f |= FLAGBIT_Z;
+ if (value & b2signbit[b])
+ f |= FLAGBIT_S;
+ if (value & ~mask
+ && (value & ~mask) != ~mask)
+ f |= FLAGBIT_O;
+ set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O, f);
+ }
+
+ void
+ set_sz (int value, int b)
+ {
+ int mask = b2mask[b];
+ int f = 0;
+
+ if ((value & mask) == 0)
+ f |= FLAGBIT_Z;
+ if (value & b2signbit[b])
+ f |= FLAGBIT_S;
+ set_flags (FLAGBIT_Z | FLAGBIT_S, f);
+ }
+
+ void
+ set_zc (int z, int c)
+ {
+ set_flags (FLAGBIT_C | FLAGBIT_Z, (c ? FLAGBIT_C : 0) | (z ? FLAGBIT_Z : 0));
+ }
+
+ void
+ set_c (int c)
+ {
+ set_flags (FLAGBIT_C, c ? FLAGBIT_C : 0);
+ }
+
+ void
+ put_reg_ll (reg_id id, DI v)
+ {
+ reg_bank_type *b = regs.r + (FLAG_B ? 1 : 0);
+
+ switch (id)
+ {
+ case r3r1r2r0:
+ b->r_r3 = v>>48;
+ b->r_r1 = v>>32;
+ b->r_r2 = v>>16;
+ b->r_r0 = v;
+ break;
+ case r3r2r1r0:
+ b->r_r3 = v>>48;
+ b->r_r2 = v>>32;
+ b->r_r1 = v>>16;
+ b->r_r0 = v;
+ break;
+ default:
+ put_reg (id, v);
+ }
+ }
+
+ #define TRC(f,n, id) \
+ if (oldregs.f != regs.f) \
+ { \
+ printf(" %s %0*x:%0*x", n, \
+ reg_bytes[id]*2, (unsigned int)oldregs.f, \
+ reg_bytes[id]*2, (unsigned int)regs.f); \
+ oldregs.f = regs.f; \
+ }
+
+ void
+ trace_register_changes ()
+ {
+ if (!trace)
+ return;
+ printf("\033[36mREGS:");
+ TRC(r[0].r_r0, "r0", r0);
+ TRC(r[0].r_r1, "r1", r1);
+ TRC(r[0].r_r2, "r2", r2);
+ TRC(r[0].r_r3, "r3", r3);
+ TRC(r[0].r_a0, "a0", a0);
+ TRC(r[0].r_a1, "a1", a1);
+ TRC(r[0].r_sb, "sb", sb);
+ TRC(r[0].r_fb, "fb", fb);
+ TRC(r[1].r_r0, "r0'", r0);
+ TRC(r[1].r_r1, "r1'", r1);
+ TRC(r[1].r_r2, "r2'", r2);
+ TRC(r[1].r_r3, "r3'", r3);
+ TRC(r[1].r_a0, "a0'", a0);
+ TRC(r[1].r_a1, "a1'", a1);
+ TRC(r[1].r_sb, "sb'", sb);
+ TRC(r[1].r_fb, "fb'", fb);
+ TRC(r_intbh, "intbh", intbh);
+ TRC(r_intbl, "intbl", intbl);
+ TRC(r_usp, "usp", usp);
+ TRC(r_isp, "isp", isp);
+ TRC(r_pc, "pc", pc);
+ TRC(r_flags, "flags", flags);
+ printf("\033[0m\n");
+ }
Index: sim/m32c/run-m32c.cc
===================================================================
RCS file: sim/m32c/run-m32c.cc
diff -N sim/m32c/run-m32c.cc
*** sim/m32c/run-m32c.cc 1 Jan 1970 00:00:00 -0000
--- sim/m32c/run-m32c.cc 6 Oct 2005 22:36:53 -0000
***************
*** 0 ****
--- 1,1140 ----
+ #include <sstream>
+ #include <string>
+ #include <iostream>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <sys/mman.h> /* mmap() is defined in this header */
+ #include <fcntl.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ extern "C" {
+ #include "elfload.h"
+ }
+
+ #define USI unsigned long
+ #define SI long
+ #define UHI unsigned short
+ #define HI short
+ #define UQI unsigned char
+ #define QI char
+
+ enum modes_t {qi=0, hi=1, si=2};
+ enum op_fetch_t {src_op=1, dest_op=0};
+
+ class m32c_cpu_type
+ {
+ public:
+
+ // CPU state information.
+
+ // Hardware elements.
+ union r2r0 {
+ int r2r0;
+ struct hi
+ {
+ HI r2;
+ HI r0;
+ } hi;
+ struct qi
+ {
+ QI r2l;
+ QI r2h;
+ QI r0l;
+ QI r0h;
+ } qi;
+ } r2r0;
+ union r3r1 {
+ int r3r1;
+ struct hi
+ {
+ HI r3;
+ HI r1;
+ } hi;
+ struct qi
+ {
+ QI r3l;
+ QI r3h;
+ QI r1l;
+ QI r1h;
+ } qi;
+ } r3r1;
+ union a1a0
+ {
+ int a1a0;
+ struct hi
+ {
+ HI a1;
+ HI a0;
+ } hi;
+ } a1a0;
+ HI h_sb;
+ HI h_sp;
+ HI h_fb;
+
+ union memory
+ {
+ QI qi [16 * 1024];
+ HI hi [8 * 1024];
+ int si [4 * 1024];
+ } memory;
+
+ /* program counter */
+ int h_pc;
+
+ /* flags */
+ union flags
+ {
+ QI flags;
+ struct
+ {
+ int u : 1;
+ int i : 1;
+ int o : 1;
+ int b : 1;
+ int s : 1;
+ int z : 1;
+ int d : 1;
+ int c : 1;
+ } flag;
+ } flags;
+
+ /* program text */
+ union text
+ {
+ QI *h_qitext;
+ HI *h_hitext;
+ } text;
+
+ inline std::string h_gregname (int regno, modes_t mode)
+ {
+ switch (regno)
+ {
+ case 0:
+ switch (mode)
+ {
+ case qi: return "r0l";
+ case hi: return "r0";
+ case si: return "r2r0";
+ }
+ case 1:
+ switch (mode)
+ {
+ case qi: return "r0h";
+ case hi: return "r1";
+ case si: return "r3r1";
+ }
+ case 2:
+ switch (mode)
+ {
+ case qi: return "r1l";
+ case hi: return "r2";
+ }
+ case 3:
+ switch (mode)
+ {
+ case qi: return "r1h";
+ case hi: return "r3";
+ }
+ }
+ }
+
+ inline std::string h_aregname (int regno, modes_t mode)
+ {
+ switch (regno)
+ {
+ case 0:
+ switch (mode)
+ {
+ case hi: return "a0";
+ case si: return "a1a0";
+ }
+ case 1:
+ switch (mode)
+ {
+ case hi: return "a1";
+ }
+ }
+ }
+
+ // C++ register access function templates
+ #define current_cpu this
+ inline int h_rget (int regno, modes_t mode) const
+ {
+ switch (mode)
+ {
+ case qi:
+ switch (regno)
+ {
+ case 0: return this->r2r0.qi.r0l;
+ case 1: return this->r2r0.qi.r0h;
+ case 2: return this->r3r1.qi.r1l;
+ case 3: return this->r3r1.qi.r1h;
+ }
+ case hi:
+ switch (regno)
+ {
+ case 0: return this->r2r0.hi.r0;
+ case 1: return this->r3r1.hi.r1;
+ case 2: return this->r2r0.hi.r2;
+ case 3: return this->r3r1.hi.r3;
+ }
+ case si:
+ switch (regno)
+ {
+ case 0: return this->r2r0.r2r0;
+ case 1: return this->r3r1.r3r1;
+ }
+ }
+ }
+
+
+ inline int h_rset (int regno, modes_t mode, int newval)
+ {
+ switch (mode)
+ {
+ case qi:
+ switch (regno)
+ {
+ case 0: return this->r2r0.qi.r0l = newval;
+ case 1: return this->r2r0.qi.r0h = newval;
+ case 2: return this->r3r1.qi.r1l = newval;
+ case 3: return this->r3r1.qi.r1h = newval;
+ }
+ case hi:
+ switch (regno)
+ {
+ case 0: return this->r2r0.hi.r0 = newval;
+ case 1: return this->r3r1.hi.r1 = newval;
+ case 2: return this->r2r0.hi.r2 = newval;
+ case 3: return this->r3r1.hi.r3 = newval;
+ }
+ case si:
+ switch (regno)
+ {
+ case 0: return this->r2r0.r2r0 = newval;
+ case 1: return this->r3r1.r3r1 = newval;
+ }
+ }
+ }
+
+ inline unsigned HI h_ahi_get (int regno) const
+ {
+ switch (regno)
+ {
+ case 1: return this->a1a0.hi.a1;
+ case 0: return this->a1a0.hi.a0;
+ }
+ }
+ inline unsigned HI h_ahi_set (int regno, HI newval)
+ {
+ switch (regno)
+ {
+ case 1: return this->a1a0.hi.a1 = newval;
+ case 0: return this->a1a0.hi.a0 = newval;
+ }
+ }
+
+ inline int h_memget (int address, modes_t mode)
+ {
+ if (mode == qi)
+ return this->memory.qi[address];
+ else if (mode == hi)
+ return this->memory.hi[address / 2];
+ else if (mode == si)
+ return this->memory.hi[address / 4];
+ }
+
+ inline int h_memset (int address, int newval, modes_t mode)
+ {
+ if (mode == qi)
+ return this->memory.qi[address] = newval;
+ else if (mode == hi)
+ return this->memory.hi[address / 2] = newval;
+ else if (mode == si)
+ return this->memory.hi[address / 4] = newval;
+ }
+
+ inline int h_sb_get () const { return this->h_sb; }
+ inline int h_fb_get () const { return this->h_fb; }
+ inline int h_sp_get () const { return this->h_sp; }
+ inline void h_sp_set (int newval) { this->h_sp = newval; }
+ inline int h_pc_get () const { return this->h_pc; }
+ inline int h_flag_c_get () const { return this->flags.flag.c; }
+ inline void h_flag_c_set (int newval) { this->flags.flag.c = newval; }
+ inline int h_flag_o_get () const { return this->flags.flag.o; }
+ inline void h_flag_o_set (int newval) { this->flags.flag.o = newval; }
+ inline int h_flag_s_get () const { return this->flags.flag.s; }
+ inline void h_flag_s_set (int newval) { this->flags.flag.s = newval; }
+ inline int h_flag_z_get () const { return this->flags.flag.z; }
+ inline void h_flag_z_set (int newval) { this->flags.flag.z = newval; }
+ inline void h_pc_inc (int newval) { this->h_pc = this->h_pc + newval; }
+ inline void h_pc_set (int newval) { this->h_pc = newval; }
+ inline void h_fb_set (int newval) { this->h_fb = newval; }
+ inline QI* h_qitext_get () const { return this->text.h_qitext; }
+ inline void h_qitext_set (QI* newval) { this->text.h_qitext = newval; }
+ inline HI* h_hitext_get () const { return this->text.h_hitext; }
+ inline void h_hitext_set (HI* newval) { this->text.h_hitext = newval; }
+
+ std::string insn_str;
+ std::string trace_str;
+ unsigned long long raw_insn;
+ } m32c_cpu;
+
+ bool disassemble = true;
+
+ bool
+ addhi_cf (HI s1, HI s2)
+ {
+ return (UHI)((UHI)s1 + (UHI)s2)
+ < (UHI)s1;
+ }
+
+ bool
+ subhi_cf (HI s1, HI s2)
+ {
+ return (UHI)s1 < (UHI)s2;
+ }
+
+ bool
+ addhi_of (HI s1, HI s2)
+ {
+ return ((((HI)s1 < 0) == ((HI)s2 < 0))
+ && (((HI)s1 < 0) != (((HI)((HI)s1 + (HI)s2)) < 0)));
+ }
+
+ bool
+ subhi_of (HI s1, HI s2)
+ {
+ return ((((HI)s1 < 0) == ((HI)s2 < 0))
+ && (((HI)s1 < 0) != (((HI)((HI)s1 - (HI)s2)) < 0)));
+ }
+
+
+ bool
+ addqi_cf (QI s1, QI s2)
+ {
+ return (UQI)((UQI)s1 + (UQI)s2)
+ < (UQI)s1;
+ }
+
+ bool
+ subqi_cf (QI s1, QI s2)
+ {
+ return (UQI)s1 < (UQI)s2;
+ }
+
+ bool
+ addqi_of (QI s1, QI s2)
+ {
+ return ((((QI)s1 < 0) == ((QI)s2 < 0))
+ && (((QI)s1 < 0) != (((QI)((QI)s1 + (QI)s2)) < 0)));
+ }
+
+ bool
+ subqi_of (QI s1, QI s2)
+ {
+ return ((((QI)s1 < 0) == ((QI)s2 < 0))
+ && (((QI)s1 < 0) != (((QI)((QI)s1 - (QI)s2)) < 0)));
+ }
+
+
+ HI
+ get_bits (const void *p, int bits, int big_p)
+ {
+ const QI *addr = (QI*)p;
+ HI data;
+ int i;
+ int bytes;
+
+ if (bits % 8 != 0)
+ abort ();
+
+ data = 0;
+ bytes = bits / 8;
+ for (i = 0; i < bytes; i++)
+ {
+ int index = big_p ? i : bytes - i - 1;
+ data = (USI)(data << 8) | (UQI)addr[index];
+ }
+ return data;
+ }
+
+ std::string int_to_string (HI x)
+ {
+ std::ostringstream o;
+ if (o << "0x" << std::hex << x)
+ return o.str();
+ return "conversion error";
+ }
+
+ int
+ get_src (int src, modes_t mode, bool inc_pc)
+ {
+ int offset;
+ QI *qi_addr;
+ HI *hi_addr;
+
+ switch (src)
+ {
+ case 0:
+ if (inc_pc)
+ m32c_cpu.insn_str = m32c_cpu.insn_str + m32c_cpu.h_gregname (0, mode) + ",";
+ // m32c_cpu.trace_str = m32c_cpu.h_gregname (0, mode) + "="
+ // + int_to_string (m32c_cpu.h_rget (0, mode));
+ return m32c_cpu.h_rget (0, mode);
+ case 1:
+ if (inc_pc)
+ m32c_cpu.insn_str = m32c_cpu.insn_str + m32c_cpu.h_gregname (1, mode);
+ // m32c_cpu.trace_str = m32c_cpu.h_gregname (1, mode) + "="
+ // + int_to_string (m32c_cpu.h_rget (1, mode));
+ return m32c_cpu.h_rget (1, mode);
+ case 2:
+ if (inc_pc)
+ m32c_cpu.insn_str = m32c_cpu.insn_str + m32c_cpu.h_gregname (2, mode);
+ // m32c_cpu.trace_str = m32c_cpu.h_gregname (2, mode) + "="
+ // + int_to_string (m32c_cpu.h_rget (2, mode));
+ return m32c_cpu.h_rget (2, mode);
+ case 3:
+ if (inc_pc)
+ m32c_cpu.insn_str = m32c_cpu.insn_str + m32c_cpu.h_gregname (3, mode);
+ // m32c_cpu.trace_str = m32c_cpu.h_gregname (3, mode) + "="
+ // + int_to_string (m32c_cpu.h_rget (3, mode));
+ return m32c_cpu.h_rget (3, mode);
+ case 4:
+ if (inc_pc)
+ m32c_cpu.insn_str = m32c_cpu.insn_str + m32c_cpu.h_aregname (0, mode);
+ // m32c_cpu.trace_str = m32c_cpu.h_aregname (0, mode) + "="
+ // + int_to_string (m32c_cpu.h_ahi_get (0));
+ return m32c_cpu.h_ahi_get (0);
+ case 5:
+ if (inc_pc)
+ m32c_cpu.insn_str = m32c_cpu.insn_str + m32c_cpu.h_aregname (1, mode);
+ // m32c_cpu.trace_str = m32c_cpu.h_aregname (1, mode) + "="
+ // + int_to_string (m32c_cpu.h_ahi_get (1));
+ return m32c_cpu.h_ahi_get (1);
+ case 6:
+ if (inc_pc)
+ m32c_cpu.insn_str = m32c_cpu.insn_str + "[a0]";
+ // m32c_cpu.trace_str = int_to_string (m32c_cpu.h_ahi_get (0)) + "="
+ // + int_to_string (m32c_cpu.h_memget (m32c_cpu.h_ahi_get (0), mode));
+ return m32c_cpu.h_memget (m32c_cpu.h_ahi_get (0), mode);
+ case 7:
+ if (inc_pc)
+ m32c_cpu.insn_str = m32c_cpu.insn_str + "[a1],";
+ // m32c_cpu.trace_str = int_to_string (m32c_cpu.h_ahi_get (1)) + "="
+ // + int_to_string (m32c_cpu.h_memget (m32c_cpu.h_ahi_get (1), mode));
+ return m32c_cpu.h_memget (m32c_cpu.h_ahi_get (1), mode);
+ case 8:
+ {
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ offset = get_bits (qi_addr, 8, 0);
+ if (inc_pc)
+ {
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset)
+ + "[a0],";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 8) + offset;
+ m32c_cpu.h_pc_inc(1);
+ }
+ // m32c_cpu.trace_str = int_to_string (m32c_cpu.h_ahi_get (0) + offset)
+ // + "=" + int_to_string (m32c_cpu.h_memget (m32c_cpu.h_ahi_get (0) + offset, qi));
+ return m32c_cpu.h_memget (m32c_cpu.h_ahi_get (0) + offset, qi);
+ }
+ case 9:
+ {
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ offset = get_bits (qi_addr, 8, 0);
+ if (inc_pc)
+ {
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset)
+ + "[a1],";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 8) + offset;
+ m32c_cpu.h_pc_inc(1);
+ }
+ // m32c_cpu.trace_str = int_to_string (m32c_cpu.h_ahi_get (1) + offset)
+ // + "=" + int_to_string (m32c_cpu.h_memget (m32c_cpu.h_ahi_get (1) + offset, qi));
+ return m32c_cpu.h_memget (m32c_cpu.h_ahi_get (1) + offset, qi);
+ }
+ case 10:
+ {
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ offset = get_bits (qi_addr, 8, 0);
+ if (inc_pc)
+ {
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset)
+ + "[sb],";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 8) + offset;
+ m32c_cpu.h_pc_inc(1);
+ }
+ // m32c_cpu.trace_str = int_to_string (m32c_cpu.h_sb_get () + offset)
+ // + "=" + int_to_string (m32c_cpu.h_memget (m32c_cpu.h_sb_get () + offset, qi));
+ return m32c_cpu.h_memget (m32c_cpu.h_sb_get () + offset, qi);
+ }
+ case 11:
+ {
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ offset = get_bits (qi_addr, 8, 0);
+ if (inc_pc)
+ {
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset)
+ + "[fb],";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 8) + offset;
+ m32c_cpu.h_pc_inc(1);
+ }
+ // m32c_cpu.trace_str = int_to_string (m32c_cpu.h_fb_get () + offset)
+ // + "=" + int_to_string (m32c_cpu.h_memget (m32c_cpu.h_fb_get () + offset, qi));
+ return m32c_cpu.h_memget (m32c_cpu.h_fb_get () + offset, qi);
+ }
+ case 12:
+ {
+ hi_addr = (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get());
+ offset = get_bits (hi_addr, 16, 0);
+ if (inc_pc)
+ {
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset)
+ + "[a0],";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 8) + offset;
+ m32c_cpu.h_pc_inc(2);
+ }
+ // m32c_cpu.trace_str = int_to_string (m32c_cpu.h_ahi_get (0) + offset)
+ // + "=" + int_to_string (m32c_cpu.h_memget (m32c_cpu.h_ahi_get (0) + offset, hi));
+ return m32c_cpu.h_memget (m32c_cpu.h_ahi_get (0) + offset, hi);
+ }
+ case 13:
+ {
+ hi_addr = (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get());
+ offset = get_bits (hi_addr, 16, 0);
+ if (inc_pc)
+ {
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset)
+ + "[a1],";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 8) + offset;
+ m32c_cpu.h_pc_inc(2);
+ }
+ // m32c_cpu.trace_str = int_to_string (m32c_cpu.h_ahi_get (1) + offset)
+ // + "=" + int_to_string (m32c_cpu.h_memget (m32c_cpu.h_ahi_get (1) + offset, hi));
+ return m32c_cpu.h_memget (m32c_cpu.h_ahi_get (1) + offset, qi);
+ }
+ case 14:
+ {
+ hi_addr = (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get());
+ offset = get_bits (hi_addr, 16, 0);
+ if (inc_pc)
+ {
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset)
+ + "[sb],";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 8) + offset;
+ m32c_cpu.h_pc_inc(2);
+ }
+ // m32c_cpu.trace_str = int_to_string (m32c_cpu.h_sb_get () + offset)
+ // + "=" + int_to_string (m32c_cpu.h_memget (m32c_cpu.h_sb_get () + offset, hi));
+ return m32c_cpu.h_memget (m32c_cpu.h_sb_get () + offset, qi);
+ }
+ case 15:
+ {
+ hi_addr = (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get());
+ offset = get_bits (hi_addr, 16, 0);
+ if (inc_pc)
+ {
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset) + ",";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 16) + offset;
+ m32c_cpu.h_pc_inc(2);
+ }
+ m32c_cpu.trace_str = int_to_string (offset) + "="
+ + int_to_string (m32c_cpu.h_memget (offset, hi)) + " ";
+ return m32c_cpu.h_memget (offset, hi);
+ }
+ }
+ }
+
+ int
+ get_imm_src (int src, modes_t mode)
+ {
+ UHI offset;
+ QI *qi_addr;
+ HI *hi_addr;
+ int size;
+
+ switch (mode)
+ {
+ case qi: size = 8; break;
+ case hi: size = 16; break;
+ case si: size = 32; break;
+ }
+
+ switch (src)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ offset = get_bits (qi_addr, size, 0);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset) + ",";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << size) + offset;
+ return offset;
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ {
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get() + 1;
+ offset = get_bits (qi_addr, size, 0);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset) + ",";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << size) + offset;
+ return offset;
+ }
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ {
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get() + 2;
+ offset = get_bits (qi_addr, size, 0);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset) + ",";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << size) + offset;
+ return offset;
+ }
+ }
+ }
+
+ int
+ put_dest (int dest, int newval, modes_t mode)
+ {
+ int offset;
+ QI *qi_addr;
+ HI *hi_addr;
+ int size;
+
+ switch (mode)
+ {
+ case qi: size = 8; break;
+ case hi: size = 16; break;
+ case si: size = 32; break;
+ }
+
+ switch (dest)
+ {
+ case 0:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ m32c_cpu.insn_str = m32c_cpu.insn_str + m32c_cpu.h_gregname (0, mode);
+ m32c_cpu.trace_str = m32c_cpu.trace_str
+ + m32c_cpu.h_gregname (0, mode) + "=" + int_to_string (newval);
+ return m32c_cpu.h_rset (0, mode, newval);
+ case 1:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ m32c_cpu.insn_str = m32c_cpu.insn_str + m32c_cpu.h_gregname (1, mode);
+ m32c_cpu.trace_str = m32c_cpu.trace_str +
+ m32c_cpu.h_gregname (1, mode) + "=" + int_to_string (newval);
+ return m32c_cpu.h_rset (1, mode, newval);
+ case 2:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ m32c_cpu.insn_str = m32c_cpu.insn_str + m32c_cpu.h_gregname (2, mode);
+ m32c_cpu.trace_str = m32c_cpu.trace_str +
+ m32c_cpu.h_gregname (2, mode) + "=" + int_to_string (newval);
+ return m32c_cpu.h_rset (2, mode, newval);
+ case 3:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ m32c_cpu.insn_str = m32c_cpu.insn_str + m32c_cpu.h_gregname (3, mode);
+ m32c_cpu.trace_str = m32c_cpu.trace_str +
+ m32c_cpu.h_gregname (3, mode) + "=" + int_to_string (newval);
+ return m32c_cpu.h_rset (3, mode, newval);
+ case 4:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ m32c_cpu.insn_str = m32c_cpu.insn_str + m32c_cpu.h_aregname (0, mode);
+ m32c_cpu.trace_str = m32c_cpu.trace_str +
+ m32c_cpu.h_aregname (0, mode) + "=" + int_to_string (newval);
+ return m32c_cpu.h_ahi_set (0, newval);
+ case 5:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ m32c_cpu.insn_str = m32c_cpu.insn_str + m32c_cpu.h_aregname (1, mode);
+ m32c_cpu.trace_str = m32c_cpu.trace_str +
+ m32c_cpu.h_aregname (1, mode) + "=" + int_to_string (newval);
+ return m32c_cpu.h_ahi_set (1, newval);
+ case 6:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ m32c_cpu.insn_str = m32c_cpu.insn_str + "[a0]";
+ m32c_cpu.trace_str = int_to_string (m32c_cpu.h_ahi_get (0)) + "="
+ + int_to_string (newval);
+ return m32c_cpu.h_memset (m32c_cpu.h_ahi_get (0), newval, mode);
+ case 7:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ m32c_cpu.insn_str = m32c_cpu.insn_str + "[a1]";
+ m32c_cpu.trace_str = int_to_string (m32c_cpu.h_ahi_get (1)) + "="
+ + int_to_string (newval);
+ return m32c_cpu.h_memset (m32c_cpu.h_ahi_get (1), newval, mode);
+ case 8:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ offset = get_bits (qi_addr, 8, 0);
+ m32c_cpu.h_pc_inc(1);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset) + "[a0]";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 8) + offset;
+ m32c_cpu.trace_str = int_to_string (m32c_cpu.h_ahi_get (0) + offset)
+ + "=" + int_to_string (newval);
+ return m32c_cpu.h_memset (m32c_cpu.h_ahi_get (0) + offset, newval, mode);
+ case 9:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ offset = get_bits (qi_addr, 8, 0);
+ m32c_cpu.h_pc_inc(1);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset) + "[a1]";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 8) + offset;
+ m32c_cpu.trace_str = int_to_string (m32c_cpu.h_ahi_get (1) + offset)
+ + "=" + int_to_string (newval);
+ return m32c_cpu.h_memset (m32c_cpu.h_ahi_get (1) + offset, newval, mode);
+ case 10:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ offset = get_bits (qi_addr, 8, 0);
+ m32c_cpu.h_pc_inc(1);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset) + "[sb]";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 8) + offset;
+ m32c_cpu.trace_str = int_to_string (m32c_cpu.h_sb_get () + offset)
+ + "=" + int_to_string (newval);
+ return m32c_cpu.h_memset (m32c_cpu.h_sb_get () + offset, newval, mode);
+ case 11:
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ offset = get_bits (qi_addr, 8, 0);
+ m32c_cpu.h_pc_inc(1);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset) + "[fb]";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 8) + offset;
+ m32c_cpu.trace_str = int_to_string (m32c_cpu.h_fb_get () + offset)
+ + "=" + int_to_string (newval);
+ return m32c_cpu.h_memset (m32c_cpu.h_fb_get () + offset, newval, mode);
+ case 12:
+ hi_addr = (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get());
+ offset = get_bits (hi_addr, 16, 0);
+ m32c_cpu.h_pc_inc(2);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset) + "[a0]";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 16) + offset;
+ m32c_cpu.trace_str = int_to_string (m32c_cpu.h_ahi_get (0) + offset)
+ + "=" + int_to_string (newval);
+ return m32c_cpu.h_memset (m32c_cpu.h_ahi_get (0) + offset, newval, mode);
+ case 13:
+ hi_addr = (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get());
+ offset = get_bits (hi_addr, 16, 0);
+ m32c_cpu.h_pc_inc(2);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset) + "[a1]";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 16) + offset;
+ m32c_cpu.trace_str = int_to_string (m32c_cpu.h_ahi_get (1) + offset)
+ + "=" + int_to_string (newval);
+ return m32c_cpu.h_memset (m32c_cpu.h_ahi_get (1) + offset, newval, mode);
+ case 14:
+ hi_addr = (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get());
+ offset = get_bits (hi_addr, 16, 0);
+ m32c_cpu.h_pc_inc(2);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset) + "[sb]";
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 16) + offset;
+ m32c_cpu.trace_str = int_to_string (m32c_cpu.h_sb_get () + offset)
+ + "=" + int_to_string (newval);
+ return m32c_cpu.h_memset (m32c_cpu.h_sb_get () + offset, newval, mode);
+ case 15:
+ hi_addr = (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get());
+ offset = get_bits (hi_addr, 16, 0);
+ m32c_cpu.h_pc_inc(2);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (offset);
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 16) + offset;
+ m32c_cpu.trace_str = int_to_string (offset) + "=" + int_to_string (newval);
+ return m32c_cpu.h_memset (offset, newval, mode);
+ }
+ }
+
+ #define BIT(n) ((unsigned long)(insn>>(15 - (n))) & 1) /* bit n of instruction */
+ #define BITS(s,l) ((unsigned long)(insn << (s + 16)) >> (32 - (l)))
+
+ enum execute_status {have_exit=1};
+
+ execute_status
+ execute_insn ()
+ {
+ QI qi_src;
+ QI qi_dest;
+ HI hi_src;
+ HI hi_dest;
+ UHI insn;
+ QI *qi_addr;
+ HI *hi_addr;
+
+ hi_addr = (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get());
+ insn = get_bits (hi_addr, 16, 1);
+ m32c_cpu.h_pc_inc(2);
+ m32c_cpu.raw_insn = insn;
+
+ // op imm,dest
+ switch (BITS (0, 12))
+ {
+ case 0x76F:
+ m32c_cpu.insn_str = "abs.b ";
+ qi_src = get_src (BITS (12, 4), qi, dest_op);
+ put_dest (BITS (12, 4), abs (qi_src), qi);
+ goto DONE_ONE_INSN;
+ case 0x77F:
+ m32c_cpu.insn_str = "abs.w ";
+ hi_src = get_src (BITS (12, 4), hi, dest_op);
+ put_dest (BITS (12, 4), abs (hi_src), hi);
+ goto DONE_ONE_INSN;
+ case 0x766:
+ m32c_cpu.insn_str = "adc.b.g ";
+ qi_src = get_imm_src (BITS (12, 4), qi);
+ qi_dest = get_src (BITS (12, 4), qi, dest_op);
+ put_dest (BITS (12, 4), qi_src + qi_dest + m32c_cpu.h_flag_c_get(), qi);
+ m32c_cpu.h_pc_inc (1); // allow for imm
+ goto DONE_ONE_INSN;
+ case 0x776:
+ m32c_cpu.insn_str = "adc.w.g ";
+ hi_src = get_imm_src (BITS (12, 4), hi);
+ hi_dest = get_src (BITS (12, 4), hi, dest_op);
+ put_dest (BITS (12, 4), hi_src + hi_dest + m32c_cpu.h_flag_c_get(), hi);
+ m32c_cpu.h_pc_inc (2); // allow for imm
+ goto DONE_ONE_INSN;
+ case 0x76E:
+ m32c_cpu.insn_str = "adcf.b ";
+ qi_src = get_src (BITS (12, 4), qi, dest_op);
+ put_dest (BITS (12, 4), qi_src + m32c_cpu.h_flag_c_get(), qi);
+ goto DONE_ONE_INSN;
+ case 0x77E:
+ m32c_cpu.insn_str = "adcf.w ";
+ hi_src = get_src (BITS (12, 4), hi, dest_op);
+ put_dest (BITS (12, 4), hi_src + m32c_cpu.h_flag_c_get(), hi);
+ goto DONE_ONE_INSN;
+ case 0x764:
+ m32c_cpu.insn_str = "add.b.g ";
+ qi_src = get_imm_src (BITS (12, 4), qi);
+ qi_dest = get_src (BITS (12, 4), qi, dest_op);
+ put_dest (BITS (12, 4), qi_src + qi_dest, qi);
+ m32c_cpu.h_pc_inc (1); // allow for imm
+ goto DONE_ONE_INSN;
+ case 0x774:
+ m32c_cpu.insn_str = "add.w.g ";
+ hi_src = get_imm_src (BITS (12, 4), hi);
+ hi_dest = get_src (BITS (12, 4), hi, dest_op);
+ put_dest (BITS (12, 4), hi_src + hi_dest, hi);
+ m32c_cpu.h_pc_inc (2); // allow for imm
+ goto DONE_ONE_INSN;
+ case 0x7DB:
+ m32c_cpu.insn_str = "add.b.q ";
+ qi_src = (signed QI) BITS (12, 4);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (qi_src) + ",sp";
+ m32c_cpu.h_sp_set (qi_src + m32c_cpu.h_sp_get());
+ goto DONE_ONE_INSN;
+ case 0x762:
+ m32c_cpu.insn_str = "and.b.g ";
+ qi_src = get_imm_src (BITS (12, 4), qi);
+ qi_dest = get_src (BITS (12, 4), qi, dest_op);
+ put_dest (BITS (12, 4), qi_src & qi_dest, qi);
+ m32c_cpu.h_pc_inc (1); // allow for imm
+ goto DONE_ONE_INSN;
+ case 0x772:
+ m32c_cpu.insn_str = "and.w.g ";
+ hi_src = get_imm_src (BITS (12, 4), hi);
+ hi_dest = get_src (BITS (12, 4), hi, dest_op);
+ put_dest (BITS (12, 4), hi_src & hi_dest, hi);
+ m32c_cpu.h_pc_inc (2); // allow for imm
+ goto DONE_ONE_INSN;
+ case 0x768:
+ m32c_cpu.insn_str = "cmp.b.g ";
+ qi_src = get_imm_src (BITS (12, 4), qi);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (qi_src);
+ qi_dest = get_src (BITS (12, 4), qi, src_op);
+ m32c_cpu.h_flag_c_set (! subqi_cf (qi_src, qi_dest));
+ m32c_cpu.h_flag_o_set (! subqi_of (qi_src, qi_dest));
+ m32c_cpu.h_flag_z_set ((qi_src - qi_dest) == 0);
+ m32c_cpu.h_flag_s_set (qi_src < qi_dest);
+ m32c_cpu.h_pc_inc (1); // allow for imm
+ goto DONE_ONE_INSN;
+ case 0x778:
+ m32c_cpu.insn_str = "cmp.w.g ";
+ hi_src = get_imm_src (BITS (12, 4), hi);
+ hi_dest = get_src (BITS (12, 4), hi, src_op);
+ m32c_cpu.h_flag_c_set (! subhi_cf (hi_src, hi_dest));
+ m32c_cpu.h_flag_o_set (! subhi_of (hi_src, hi_dest));
+ m32c_cpu.h_flag_z_set ((hi_src - hi_dest) == 0);
+ m32c_cpu.h_flag_s_set (hi_src < hi_dest);
+ m32c_cpu.h_pc_inc (2); // allow for imm
+ goto DONE_ONE_INSN;
+ case 0x76D:
+ {
+ QI quotient;
+ QI remainder;
+ m32c_cpu.insn_str = "div.b ";
+ qi_src = get_src (BITS (12, 4), qi, src_op);
+ quotient = m32c_cpu.h_rget (0, hi) / qi_src;
+ remainder = m32c_cpu.h_rget (0, hi) % qi_src;
+ m32c_cpu.h_rset (0, qi, quotient);
+ m32c_cpu.h_rset (1, qi, remainder);
+ m32c_cpu.trace_str = m32c_cpu.trace_str
+ + m32c_cpu.h_gregname (0, qi) + "=" + int_to_string (quotient) + " "
+ + m32c_cpu.h_gregname (1, qi)
+ + "=" + int_to_string (remainder);
+ goto DONE_ONE_INSN;
+ }
+ case 0x77D:
+ {
+ HI quotient;
+ HI remainder;
+ m32c_cpu.insn_str = "div.w ";
+ hi_src = get_src (BITS (12, 4), hi, src_op);
+ quotient = m32c_cpu.h_rget (0, si) / hi_src;
+ remainder = m32c_cpu.h_rget (0, si) % hi_src;
+ m32c_cpu.h_rset (0, hi, quotient);
+ m32c_cpu.h_rset (1, hi, remainder);
+ m32c_cpu.trace_str = m32c_cpu.trace_str
+ + m32c_cpu.h_gregname (0, hi) + "="
+ + int_to_string (quotient) + " " + m32c_cpu.h_gregname (1, hi) + "="
+ + int_to_string (remainder);
+ goto DONE_ONE_INSN;
+ }
+ case 0x76C:
+ {
+ QI quotient;
+ QI remainder;
+ m32c_cpu.insn_str = "divu.b ";
+ qi_src = get_src (BITS (12, 4), qi, src_op);
+ quotient = (UHI)m32c_cpu.h_rget (0, hi) / (UQI)qi_src;
+ remainder = (UHI)m32c_cpu.h_rget (0, hi) % (UQI)qi_src;
+ m32c_cpu.h_rset (0, qi, quotient);
+ m32c_cpu.h_rset (1, qi, remainder);
+ m32c_cpu.trace_str = m32c_cpu.trace_str
+ + m32c_cpu.h_gregname (0, qi) + "="
+ + int_to_string (quotient) + " " + m32c_cpu.h_gregname (1, qi) + "="
+ + int_to_string (remainder);
+ goto DONE_ONE_INSN;
+ }
+ case 0x77C:
+ {
+ HI quotient;
+ HI remainder;
+ m32c_cpu.insn_str = "divu.w ";
+ hi_src = get_src (BITS (12, 4), hi, src_op);
+ quotient = (USI)m32c_cpu.h_rget (0, si) / (UHI)hi_src;
+ remainder = (USI)m32c_cpu.h_rget (0, si) % (UHI)hi_src;
+ m32c_cpu.h_rset (0, hi, quotient);
+ m32c_cpu.h_rset (1, hi, remainder);
+ m32c_cpu.trace_str = m32c_cpu.trace_str
+ + m32c_cpu.h_gregname (0, hi) + "="
+ + int_to_string (quotient) + " " + m32c_cpu.h_gregname (1, hi) + "="
+ + int_to_string (remainder);
+ goto DONE_ONE_INSN;
+ }
+ case 0x74C:
+ m32c_cpu.insn_str = "mov.b ";
+ qi_src = get_imm_src (BITS (12, 4), qi);
+ put_dest (BITS (12, 4), qi_src, qi);
+ m32c_cpu.h_pc_inc (1); // allow for imm
+ goto DONE_ONE_INSN;
+ case 0x75C:
+ m32c_cpu.insn_str = "mov.w ";
+ hi_src = get_imm_src (BITS (12, 4), hi);
+ put_dest (BITS (12, 4), hi_src, hi);
+ m32c_cpu.h_pc_inc (2); // allow for imm
+ goto DONE_ONE_INSN;
+ default:
+ break;
+ }
+
+ // op src,dest
+ switch (BITS (0, 8))
+ {
+ case 0xB0:
+ m32c_cpu.insn_str = "adc.b.g ";
+ qi_src = get_src (BITS (8, 4), qi, src_op);
+ qi_dest = get_src (BITS (12, 4), qi, dest_op);
+ put_dest (BITS (12, 4), qi_src + qi_dest + m32c_cpu.h_flag_c_get(), qi);
+ goto DONE_ONE_INSN;
+ case 0xB1:
+ m32c_cpu.insn_str = "adc.w.g ";
+ hi_src = get_src (BITS (8, 4), hi, src_op);
+ hi_dest = get_src (BITS (12, 4), hi, dest_op);
+ put_dest (BITS (12, 4), hi_src + hi_dest + m32c_cpu.h_flag_c_get(), hi);
+ goto DONE_ONE_INSN;
+ case 0xA0:
+ m32c_cpu.insn_str = "add.b.g ";
+ qi_src = get_src (BITS (8, 4), qi, src_op);
+ qi_dest = get_src (BITS (12, 4), qi, dest_op);
+ put_dest (BITS (12, 4), qi_src + qi_dest, qi);
+ goto DONE_ONE_INSN;
+ case 0xA1:
+ m32c_cpu.insn_str = "add.w.g ";
+ hi_src = get_src (BITS (8, 4), hi, src_op);
+ hi_dest = get_src (BITS (12, 4), hi, dest_op);
+ put_dest (BITS (12, 4), hi_src + hi_dest, hi);
+ goto DONE_ONE_INSN;
+ case 0xC8:
+ m32c_cpu.insn_str = "add.b.q ";
+ qi_src = (signed QI) BITS (8, 4);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (qi_src) + ",";
+ qi_dest = get_src (BITS (12, 4), qi, dest_op);
+ put_dest (BITS (12, 4), qi_src + qi_dest, qi);
+ goto DONE_ONE_INSN;
+ case 0xC9:
+ m32c_cpu.insn_str = "add.w.q ";
+ hi_src = (signed HI) BITS (8, 4);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (hi_src) + ",";
+ hi_dest = get_src (BITS (12, 4), hi, dest_op);
+ put_dest (BITS (12, 4), hi_src + hi_dest, hi);
+ goto DONE_ONE_INSN;
+ case 0x90:
+ m32c_cpu.insn_str = "and.b.g ";
+ qi_src = get_src (BITS (8, 4), qi, src_op);
+ qi_dest = get_src (BITS (12, 4), qi, dest_op);
+ put_dest (BITS (12, 4), qi_src & qi_dest, qi);
+ goto DONE_ONE_INSN;
+ case 0x91:
+ m32c_cpu.insn_str = "and.w.g ";
+ hi_src = get_src (BITS (8, 4), hi, src_op);
+ hi_dest = get_src (BITS (12, 4), hi, dest_op);
+ put_dest (BITS (12, 4), hi_src & hi_dest, hi);
+ goto DONE_ONE_INSN;
+ case 0xC0:
+ m32c_cpu.insn_str = "cmp.b.g ";
+ qi_src = get_src (BITS (8, 4), qi, src_op);
+ qi_dest = get_src (BITS (12, 4), qi, src_op);
+ m32c_cpu.h_flag_c_set (! subqi_cf (qi_src, qi_dest));
+ m32c_cpu.h_flag_o_set (! subqi_of (qi_src, qi_dest));
+ m32c_cpu.h_flag_z_set ((qi_src - qi_dest) == 0);
+ m32c_cpu.h_flag_s_set (qi_src < qi_dest);
+ goto DONE_ONE_INSN;
+ case 0xC1:
+ m32c_cpu.insn_str = "cmp.w.g ";
+ hi_src = get_src (BITS (8, 4), hi, src_op);
+ hi_dest = get_src (BITS (12, 4), hi, src_op);
+ m32c_cpu.h_flag_c_set (! subhi_cf (hi_src, hi_dest));
+ m32c_cpu.h_flag_o_set (! subhi_of (hi_src, hi_dest));
+ m32c_cpu.h_flag_z_set ((hi_src - hi_dest) == 0);
+ m32c_cpu.h_flag_s_set (hi_src < hi_dest);
+ goto DONE_ONE_INSN;
+ case 0xD0:
+ m32c_cpu.insn_str = "cmp.b.q ";
+ qi_src = (signed QI) BITS (8, 4);
+ qi_dest = get_src (BITS (12, 4), qi, dest_op);
+ m32c_cpu.h_flag_c_set (! subqi_cf (qi_src, qi_dest));
+ m32c_cpu.h_flag_o_set (! subqi_of (qi_src, qi_dest));
+ m32c_cpu.h_flag_z_set ((qi_src - qi_dest) == 0);
+ m32c_cpu.h_flag_s_set (qi_src < qi_dest);
+ goto DONE_ONE_INSN;
+ case 0xD1:
+ m32c_cpu.insn_str = "cmp.w.q ";
+ hi_src = (signed HI) BITS (8, 4);
+ hi_dest = get_src (BITS (12, 4), hi, dest_op);
+ m32c_cpu.h_flag_c_set (! subhi_cf (hi_src, hi_dest));
+ m32c_cpu.h_flag_o_set (! subhi_of (hi_src, hi_dest));
+ m32c_cpu.h_flag_z_set ((hi_src - hi_dest) == 0);
+ m32c_cpu.h_flag_s_set (hi_src < hi_dest);
+ goto DONE_ONE_INSN;
+ case 0x72:
+ m32c_cpu.insn_str = "mov.b ";
+ qi_src = get_src (BITS (8, 4), qi, src_op);
+ put_dest (BITS (12, 4), (qi_src), qi);
+ goto DONE_ONE_INSN;
+ case 0x73:
+ m32c_cpu.insn_str = "mov.w ";
+ hi_src = get_src (BITS (8, 4), hi, src_op);
+ put_dest (BITS (12, 4), (hi_src), hi);
+ goto DONE_ONE_INSN;
+ case 0x04:
+ m32c_cpu.insn_str = "nop ";
+ m32c_cpu.h_pc_inc (1);
+ goto DONE_ONE_INSN;
+ case 0xEB:
+ return have_exit;
+ default:
+ goto DONE_ONE_INSN;
+ }
+
+ switch (BITS (0, 12))
+ {
+ case 0x7CF2:
+ m32c_cpu.insn_str = "enter ";
+ qi_addr = m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get();
+ qi_src = get_bits (qi_addr, 8, 0);
+ m32c_cpu.insn_str = m32c_cpu.insn_str + int_to_string (qi_src);
+ m32c_cpu.raw_insn = (m32c_cpu.raw_insn << 8) + qi_src;
+ m32c_cpu.h_sp_set (m32c_cpu.h_sp_get() - 2);
+ m32c_cpu.h_memset (m32c_cpu.h_sp_get(), m32c_cpu.h_fb_get(), hi);
+ m32c_cpu.h_fb_set (m32c_cpu.h_sp_get());
+ m32c_cpu.h_sp_set (m32c_cpu.h_sp_get() - qi_src);
+ m32c_cpu.trace_str = "fb=" + int_to_string (m32c_cpu.h_fb_get()) + " sp="
+ + int_to_string (m32c_cpu.h_sp_get());
+ m32c_cpu.h_pc_inc (1);
+ }
+
+ DONE_ONE_INSN:
+ if (disassemble)
+ {
+ std::cout << std::hex << m32c_cpu.raw_insn << "\t";
+ std::cout << m32c_cpu.insn_str << "\t";
+ std::cout << m32c_cpu.trace_str << std::endl;
+ std::cout << std::hex << m32c_cpu.h_pc_get() << " ";
+ m32c_cpu.raw_insn = 0;
+ m32c_cpu.insn_str = "";
+ m32c_cpu.trace_str = "";
+ }
+ // TODO add(3) add(5) adjnz and(2) and(4) b* cmp(3) cmp(5) dadc dadd dec
+ // div(1) divu(1) divx dsbb dsub
+ }
+
+ const struct TextSection *section_table;
+
+ int
+ main (int argc, QI **argv)
+ {
+ int fdin;
+ QI *src;
+ struct stat statbuf;
+ USI entry;
+ int endian;
+ USI e_flags;
+ int text_end;
+
+ if (argc != 2)
+ {
+ std::cout << "usage:" << argv[0] << "Executable-File" << std::endl;
+ exit (1);
+ }
+
+ /* open the input file */
+ if ((fdin = open (argv[1], O_RDONLY)) < 0)
+ {
+ std::cout << "Cannot open" << argv[1] << std::endl;
+ exit (1);
+ }
+
+ /* find size of input file */
+ if (fstat (fdin,&statbuf) < 0)
+ {
+ std::cout << "fstat error" << std::endl;
+ exit (1);
+ }
+
+ /* mmap the input file */
+ if ((src = (QI*) mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0))
+ == (caddr_t) -1)
+ {
+ std::cout << "mmap error for input" << std::endl;
+ exit (1);
+ }
+
+
+ if (! readElfFile (src, &entry, &endian, &e_flags, §ion_table,
+ m32c_cpu.memory.qi))
+ {
+ std::cout << "File is not an Elf Executable" << std::endl;
+ exit (1);
+ }
+
+ // m32c_cpu.h_pc_set (textSectionOffset());
+ // m32c_cpu.h_hitext_set ((HI*)src);
+ // memcpy (m32c_cpu.memory.qi, src + textSectionOffset(), textSectionEnd());
+ munmap(0, statbuf.st_size);
+ m32c_cpu.h_pc_set (entry);
+ m32c_cpu.h_qitext_set (m32c_cpu.memory.qi);
+ text_end = m32c_cpu.h_pc_get() + textSectionEnd();
+
+ for (int i = 0; m32c_cpu.h_pc_get() <= text_end; i++)
+ {
+ if (execute_insn () == have_exit)
+ break;
+ }
+ }
Index: sim/m32c/safe-fgets.c
===================================================================
RCS file: sim/m32c/safe-fgets.c
diff -N sim/m32c/safe-fgets.c
*** sim/m32c/safe-fgets.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/safe-fgets.c 6 Oct 2005 22:36:53 -0000
***************
*** 0 ****
--- 1,47 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ #include "safe-fgets.h"
+
+ static char *line_buf = 0;
+ static int line_buf_size = 0;
+
+ #define LBUFINCR 100
+
+ char *
+ safe_fgets(FILE *f)
+ {
+ char *line_ptr;
+
+ if (line_buf == 0)
+ {
+ line_buf = (char *)malloc(LBUFINCR);
+ line_buf_size = LBUFINCR;
+ }
+
+ /* points to last byte */
+ line_ptr = line_buf + line_buf_size - 1;
+
+ /* so we can see if fgets put a 0 there */
+ *line_ptr = 1;
+ if (fgets(line_buf, line_buf_size, f) == 0)
+ return 0;
+
+ /* we filled the buffer? */
+ while (line_ptr[0] == 0 && line_ptr[-1] != '\n')
+ {
+ /* Make the buffer bigger and read more of the line */
+ line_buf_size += LBUFINCR;
+ line_buf = (char *) realloc (line_buf, line_buf_size);
+
+ /* points to last byte again */
+ line_ptr = line_buf + line_buf_size - 1;
+ /* so we can see if fgets put a 0 there */
+ *line_ptr = 1;
+
+ if (fgets(line_buf+line_buf_size-LBUFINCR-1, LBUFINCR+1, f) == 0)
+ return 0;
+ }
+
+ return line_buf;
+ }
Index: sim/m32c/safe-fgets.h
===================================================================
RCS file: sim/m32c/safe-fgets.h
diff -N sim/m32c/safe-fgets.h
*** sim/m32c/safe-fgets.h 1 Jan 1970 00:00:00 -0000
--- sim/m32c/safe-fgets.h 6 Oct 2005 22:36:53 -0000
***************
*** 0 ****
--- 1,6 ----
+ #ifndef _safe_gets_h_
+ #define _safe_gets_h_
+
+ char* safe_fgets(FILE *f);
+
+ #endif
Index: sim/m32c/sample.S
===================================================================
RCS file: sim/m32c/sample.S
diff -N sim/m32c/sample.S
*** sim/m32c/sample.S 1 Jan 1970 00:00:00 -0000
--- sim/m32c/sample.S 6 Oct 2005 22:36:53 -0000
***************
*** 0 ****
--- 1,7 ----
+ .text
+
+ .global _start
+ _start:
+ mov.w #0x1234,r1
+ mov.w r1,r3 | sha.w #-8,r3 | sha.w #-7,r3
+ brk
Index: sim/m32c/sample.ld
===================================================================
RCS file: sim/m32c/sample.ld
diff -N sim/m32c/sample.ld
*** sim/m32c/sample.ld 1 Jan 1970 00:00:00 -0000
--- sim/m32c/sample.ld 6 Oct 2005 22:36:53 -0000
***************
*** 0 ****
--- 1,19 ----
+ ENTRY(_start)
+
+ MEMORY {
+ RAM1 (w) : ORIGIN = 0xc800, LENGTH = 0x0200
+ RAM2 (w) : ORIGIN = 0xca56, LENGTH = 0x1000
+ ROM (w) : ORIGIN = 0x30000, LENGTH = 0x1000
+ }
+
+ SECTIONS {
+ .data : {
+ *(.data*)
+ } > RAM1
+ .text : {
+ *(.text*)
+ } > RAM2
+ .fardata : {
+ *(.fardata*)
+ } > ROM
+ }
Index: sim/m32c/sample2.c
===================================================================
RCS file: sim/m32c/sample2.c
diff -N sim/m32c/sample2.c
*** sim/m32c/sample2.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/sample2.c 6 Oct 2005 22:36:53 -0000
***************
*** 0 ****
--- 1,7 ----
+ void exit(int);
+
+ start()
+ {
+ foo(1,2,3,4);
+ exit(5);
+ }
Index: sim/m32c/srcdest.c
===================================================================
RCS file: sim/m32c/srcdest.c
diff -N sim/m32c/srcdest.c
*** sim/m32c/srcdest.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/srcdest.c 6 Oct 2005 22:36:53 -0000
***************
*** 0 ****
--- 1,599 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ #include "cpu.h"
+ #include "mem.h"
+
+ static int src_indirect = 0;
+ static int dest_indirect = 0;
+ static int src_addend = 0;
+ static int dest_addend = 0;
+
+ static int disp8()
+ {
+ int rv;
+ int tsave = trace;
+
+ if (trace == 1)
+ trace = 0;
+ rv = mem_get_qi (get_reg (pc));
+ regs.r_pc ++;
+ trace = tsave;
+ return rv;
+ }
+
+ static int disp16()
+ {
+ int rv;
+ int tsave = trace;
+
+ if (trace == 1)
+ trace = 0;
+ rv = mem_get_hi (get_reg (pc));
+ regs.r_pc += 2;
+ trace = tsave;
+ return rv;
+ }
+
+ static int disp24()
+ {
+ int rv;
+ int tsave = trace;
+
+ if (trace == 1)
+ trace = 0;
+ rv= mem_get_psi (get_reg (pc));
+ regs.r_pc += 3;
+ trace = tsave;
+ return rv;
+ }
+
+ static int disp20()
+ {
+ return disp24() & 0x000fffff;
+ }
+
+ const char *
+ bits (int v, int b)
+ {
+ static char buf[17];
+ char *bp = buf+16;
+ *bp = 0;
+ while (b)
+ {
+ *--bp = (v & 1) ? '1' : '0';
+ v >>= 1;
+ b--;
+ }
+ return bp;
+ }
+
+ static const char *the_bits = 0;
+
+ void
+ decode_indirect (int si, int di)
+ {
+ src_indirect = si;
+ dest_indirect = di;
+ if (trace && (si || di))
+ printf("indirect: s:%d d:%d\n", si, di);
+ }
+
+ void
+ decode_index (int sa, int da)
+ {
+ src_addend = sa;
+ dest_addend = da;
+ if (trace && (sa || da))
+ printf("index: s:%d d:%d\n", sa, da);
+ }
+
+ srcdest
+ decode_srcdest4 (int destcode, int bw)
+ {
+ srcdest sd;
+ sd.bytes = bw ? 2 : 1;
+ sd.mem = (destcode >= 6) ? 1 : 0;
+ static const char *dc_wnames[16] = {"r0", "r1", "r2", "r3",
+ "a0", "a1", "[a0]", "[a1]",
+ "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]",
+ "disp16[a0]", "disp16[a1]", "disp16[sb]", "disp16"};
+ static const char *dc_bnames[4] = {"r0l", "r0h", "r1l", "r1h"};;
+
+ if (trace)
+ {
+ const char *n = dc_wnames[destcode];
+ if (bw == 0 && destcode <= 3)
+ n = dc_bnames[destcode];
+ if (!the_bits)
+ the_bits = bits(destcode, 4);
+ printf("decode: %s (%d) : %s\n", the_bits, destcode, n);
+ the_bits = 0;
+ }
+
+ switch (destcode)
+ {
+ case 0x0: sd.u.reg = bw ? r0 : r0l; break;
+ case 0x1: sd.u.reg = bw ? r1 : r0h; break;
+ case 0x2: sd.u.reg = bw ? r2 : r1l; break;
+ case 0x3: sd.u.reg = bw ? r3 : r1h; break;
+ case 0x4: sd.u.reg = a0; break;
+ case 0x5: sd.u.reg = a1; break;
+ case 0x6: sd.u.addr = get_reg (a0); break;
+ case 0x7: sd.u.addr = get_reg (a1); break;
+ case 0x8: sd.u.addr = get_reg (a0) + disp8(); break;
+ case 0x9: sd.u.addr = get_reg (a1) + disp8(); break;
+ case 0xa: sd.u.addr = get_reg (sb) + disp8(); break;
+ case 0xb: sd.u.addr = get_reg (fb) + sign_ext (disp8(), 8); break;
+ case 0xc: sd.u.addr = get_reg (a0) + disp16(); break;
+ case 0xd: sd.u.addr = get_reg (a1) + disp16(); break;
+ case 0xe: sd.u.addr = get_reg (sb) + disp16(); break;
+ case 0xf: sd.u.addr = disp16(); break;
+ default: abort();
+ }
+ if (sd.mem)
+ sd.u.addr &= addr_mask;
+ return sd;
+ }
+
+ srcdest
+ decode_jumpdest (int destcode, int w)
+ {
+ srcdest sd;
+ sd.bytes = w ? 2 : 3;
+ sd.mem = (destcode >= 6) ? 1 : 0;
+ static const char *dc_wnames[16] = {"r0", "r1", "r2", "r3",
+ "a0", "a1", "[a0]", "[a1]",
+ "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]",
+ "disp20[a0]", "disp20[a1]", "disp16[sb]", "abs16"};
+ static const char *dc_anames[4] = {"r0l", "r0h", "r1l", "r1h"};
+
+ if (trace)
+ {
+ const char *n = dc_wnames[destcode];
+ if (w == 0 && destcode <= 3)
+ n = dc_anames[destcode];
+ if (!the_bits)
+ the_bits = bits(destcode, 4);
+ printf("decode: %s : %s\n", the_bits, n);
+ the_bits = 0;
+ }
+
+ switch (destcode)
+ {
+ case 0x0: sd.u.reg = w ? r0 : r2r0; break;
+ case 0x1: sd.u.reg = w ? r1 : r2r0; break;
+ case 0x2: sd.u.reg = w ? r2 : r3r1; break;
+ case 0x3: sd.u.reg = w ? r3 : r3r1; break;
+ case 0x4: sd.u.reg = w ? a0 : a1a0; break;
+ case 0x5: sd.u.reg = w ? a1 : a1a0; break;
+ case 0x6: sd.u.addr = get_reg (a0); break;
+ case 0x7: sd.u.addr = get_reg (a1); break;
+ case 0x8: sd.u.addr = get_reg (a0) + disp8(); break;
+ case 0x9: sd.u.addr = get_reg (a1) + disp8(); break;
+ case 0xa: sd.u.addr = get_reg (sb) + disp8(); break;
+ case 0xb: sd.u.addr = get_reg (fb) + sign_ext (disp8(), 8); break;
+ case 0xc: sd.u.addr = get_reg (a0) + disp20(); break;
+ case 0xd: sd.u.addr = get_reg (a1) + disp20(); break;
+ case 0xe: sd.u.addr = get_reg (sb) + disp16(); break;
+ case 0xf: sd.u.addr = disp16(); break;
+ default: abort();
+ }
+ if (sd.mem)
+ sd.u.addr &= addr_mask;
+ return sd;
+ }
+
+ srcdest
+ decode_dest3 (int destcode, int bw)
+ {
+ static char map[8] = { -1, -1, -1, 1, 0, 10, 11, 15 };
+
+ the_bits = bits(destcode, 3);
+ return decode_srcdest4(map[destcode], bw);
+ }
+
+ srcdest
+ decode_src2 (int srccode, int bw, int d)
+ {
+ static char map[4] = { 0, 10, 11, 15 };
+
+ the_bits = bits(srccode, 2);
+ return decode_srcdest4(srccode ? map[srccode] : 1-d, bw);
+ }
+
+ static struct {
+ reg_id b_regno;
+ reg_id w_regno;
+ int is_memory;
+ int disp_bytes;
+ char *name;
+ } modes23[] = {
+ { a0, a0, 1, 0, "[A0]"}, /* 0 0 0 0 0 */
+ { a1, a1, 1, 0, "[A1]" }, /* 0 0 0 0 1 */
+ { a0, a0, 0, 0, "A0" }, /* 0 0 0 1 0 */
+ { a1, a1, 0, 0, "A1" }, /* 0 0 0 1 1 */
+ { a0, a0, 1, 1, "dsp:8[A0]" }, /* 0 0 1 0 0 */
+ { a1, a1, 1, 1, "dsp:8[A1]" }, /* 0 0 1 0 1 */
+ { sb, sb, 1, 1, "dsp:8[SB]" }, /* 0 0 1 1 0 */
+ { fb, fb, 1, -1, "dsp:8[FB]" }, /* 0 0 1 1 1 */
+ { a0, a0, 1, 2, "dsp:16[A0]" }, /* 0 1 0 0 0 */
+ { a1, a1, 1, 2, "dsp:16[A1]" }, /* 0 1 0 0 1 */
+ { sb, sb, 1, 2, "dsp:16[SB]" }, /* 0 1 0 1 0 */
+ { fb, fb, 1, -2, "dsp:16[FB]" }, /* 0 1 0 1 1 */
+ { a0, a0, 1, 3, "dsp:24[A0]" }, /* 0 1 1 0 0 */
+ { a1, a1, 1, 3, "dsp:24[A1]" }, /* 0 1 1 0 1 */
+ { mem, mem, 1, 3, "abs24" }, /* 0 1 1 1 0 */
+ { mem, mem, 1, 2, "abs16" }, /* 0 1 1 1 1 */
+ { r0h, r2, 0, 0, "R0H/R2" }, /* 1 0 0 0 0 */
+ { r1h, r3, 0, 0, "R1H/R3" }, /* 1 0 0 0 1 */
+ { r0l, r0, 0, 0, "R0L/R0" }, /* 1 0 0 1 0 */
+ { r1l, r1, 0, 0, "R1L/R1" }, /* 1 0 0 1 1 */
+ };
+
+ static srcdest
+ decode_sd23 (int bbb, int bb, int bytes, int ind, int add)
+ {
+ srcdest sd;
+ int code = (bbb << 2) | bb;
+
+ if (code >= sizeof (modes23) / sizeof (modes23[0]))
+ abort();
+
+ if (trace)
+ {
+ char *b1 = "";
+ char *b2 = "";
+ char ad[30];
+ if (ind)
+ {
+ b1 = "[";
+ b2 = "]";
+ }
+ if (add)
+ sprintf(ad, "%+d", add);
+ else
+ ad[0] = 0;
+ if (!the_bits)
+ the_bits = bits(code, 4);
+ printf("decode: %s (%d) : %s%s%s%s\n", the_bits, code, b1, modes23[code].name, ad, b2);
+ the_bits = 0;
+ }
+
+ sd.bytes = bytes;
+ sd.mem = modes23[code].is_memory;
+ if (sd.mem)
+ {
+ if (modes23[code].w_regno == mem)
+ sd.u.addr = 0;
+ else
+ sd.u.addr = get_reg (modes23[code].w_regno);
+ switch (modes23[code].disp_bytes)
+ {
+ case 1:
+ sd.u.addr += disp8 ();
+ break;
+ case 2:
+ sd.u.addr += disp16 ();
+ break;
+ case -1:
+ sd.u.addr += sign_ext (disp8 (), 8);
+ break;
+ case -2:
+ sd.u.addr += sign_ext (disp16 (), 16);
+ break;
+ case 3:
+ sd.u.addr += disp24 ();
+ break;
+ default:
+ break;
+ }
+ if (add)
+ sd.u.addr += add;
+ if (ind)
+ sd.u.addr = mem_get_si (sd.u.addr & membus_mask);
+ sd.u.addr &= membus_mask;
+ }
+ else
+ {
+ sd.u.reg = (bytes>1) ? modes23[code].w_regno : modes23[code].b_regno;
+ if (bytes == 3 || bytes == 4)
+ {
+ switch (sd.u.reg)
+ {
+ case r0: sd.u.reg = r2r0; break;
+ case r1: sd.u.reg = r3r1; break;
+ case r2: abort();
+ case r3: abort();
+ default: ;
+ }
+ }
+
+ }
+ return sd;
+ }
+
+ srcdest
+ decode_dest23 (int ddd, int dd, int bytes)
+ {
+ return decode_sd23 (ddd, dd, bytes, dest_indirect, dest_addend);
+ }
+
+ srcdest
+ decode_src23 (int sss, int ss, int bytes)
+ {
+ return decode_sd23 (sss, ss, bytes, src_indirect, src_addend);
+ }
+
+ srcdest
+ decode_dest2 (int dd, int bytes)
+ {
+ /* r0l/r0, abs16, dsp:8[SB], dsp:8[FB] */
+ static char map[4] = { 0x12, 0x0f, 0x06, 0x07 };
+
+ the_bits = bits(dd, 2);
+ return decode_sd23 (map[dd]>>2, map[dd]&3, bytes, dest_indirect, dest_addend);
+ }
+
+ srcdest
+ decode_src3 (int sss, int bytes)
+ {
+ /* r0, r1, a0, a1, r2, r3, N/A, N/A */
+ static char map[8] = { 0x12, 0x13, 0x02, 0x03, 0x10, 0x11, 0, 0 };
+
+ the_bits = bits(sss, 3);
+ return decode_sd23 (map[sss]>>2, map[sss]&3, bytes, src_indirect, src_addend);
+ }
+
+ srcdest
+ decode_dest1 (int destcode, int bw)
+ {
+ the_bits = bits(destcode, 1);
+ return decode_srcdest4(destcode, bw);
+ }
+
+ srcdest
+ decode_cr (int crcode)
+ {
+ static int regcode[] = { 0, intbl, intbh, flags, isp, sp, sb, fb };
+ srcdest sd;
+ sd.mem = 0;
+ sd.bytes = 2;
+ sd.u.reg = regcode[crcode & 7];
+ return sd;
+ }
+
+ srcdest
+ decode_cr_b (int crcode, int bank)
+ {
+ /* FIXME: intbl, intbh, isp */
+ static int regcode[3][8] = {
+ { 0, 0, flags, 0, 0, 0, 0, 0 },
+ { intb, sp, sb, fb, 0, 0, 0, isp },
+ { 0, 0, 0, 0, 0, 0, 0, 0 }};
+ srcdest sd;
+ sd.mem = 0;
+ sd.bytes = bank ? 3 : 2;
+ sd.u.reg = regcode[bank][crcode & 7];
+ return sd;
+ }
+
+ srcdest
+ widen_sd (srcdest sd)
+ {
+ sd.bytes *= 2;
+ if (!sd.mem)
+ switch (sd.u.reg)
+ {
+ case r0l: sd.u.reg = r0; break;
+ case r0: sd.u.reg = r2r0; break;
+ case r1l: sd.u.reg = r1; break;
+ case r1: sd.u.reg = r3r1; break;
+ case a0:
+ if (A16)
+ sd.u.reg = a1a0;
+ break;
+ default: break;
+ }
+ return sd;
+ }
+
+ srcdest
+ reg_sd (reg_id reg)
+ {
+ srcdest rv;
+ rv.bytes = reg_bytes[reg];
+ rv.mem = 0;
+ rv.u.reg = reg;
+ return rv;
+ }
+
+ int
+ get_src (srcdest sd)
+ {
+ int v;
+ if (sd.mem)
+ {
+ switch (sd.bytes)
+ {
+ case 1:
+ v = mem_get_qi (sd.u.addr);
+ break;
+ case 2:
+ v = mem_get_hi (sd.u.addr);
+ break;
+ case 3:
+ v = mem_get_psi (sd.u.addr);
+ break;
+ case 4:
+ v = mem_get_si (sd.u.addr);
+ break;
+ default:
+ abort();
+ }
+ }
+ else
+ {
+ v = get_reg (sd.u.reg);
+ switch (sd.bytes)
+ {
+ case 1: v &= 0xff; break;
+ case 2: v &= 0xffff; break;
+ case 3: v &= 0xffffff; break;
+ }
+ }
+ return v;
+ }
+
+ void
+ put_dest (srcdest sd, int v)
+ {
+ if (sd.mem)
+ {
+ switch (sd.bytes)
+ {
+ case 1:
+ mem_put_qi (sd.u.addr, v);
+ break;
+ case 2:
+ mem_put_hi (sd.u.addr, v);
+ break;
+ case 3:
+ mem_put_psi (sd.u.addr, v);
+ break;
+ case 4:
+ mem_put_si (sd.u.addr, v);
+ break;
+ }
+ }
+ else
+ {
+ switch (sd.bytes)
+ {
+ case 1: v &= 0xff; break;
+ case 2: v &= 0xffff; break;
+ case 3: v &= 0xffffff; break;
+ }
+ put_reg (sd.u.reg, v);
+ }
+ }
+
+ srcdest
+ decode_bit (int destcode)
+ {
+ srcdest sd;
+ int addr = 0;
+ static const char *dc_names[] = {"r0", "r1", "r2", "r3",
+ "a0", "a1", "[a0]", "[a1]",
+ "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]",
+ "disp16[a0]", "disp16[a1]", "disp16[sb]", "abs16"};
+
+ if (trace)
+ {
+ const char *the_bits = bits(destcode, 4);
+ printf("decode: %s : %s\n", the_bits, dc_names[destcode]);
+ }
+
+ switch (destcode)
+ {
+ case 0: sd.u.reg = r0; break;
+ case 1: sd.u.reg = r1; break;
+ case 2: sd.u.reg = r2; break;
+ case 3: sd.u.reg = r3; break;
+ case 4: sd.u.reg = a0; break;
+ case 5: sd.u.reg = a1; break;
+ case 6: addr = get_reg (a0); break;
+ case 7: addr = get_reg (a1); break;
+ case 8: addr = get_reg (a0) + disp8 (); break;
+ case 9: addr = get_reg (a1) + disp8 (); break;
+ case 10: addr = get_reg (sb)*8 + disp8 (); break;
+ case 11: addr = get_reg (fb)*8 + sign_ext (disp8 (), 8); break;
+ case 12: addr = get_reg (a0) + disp16 (); break;
+ case 13: addr = get_reg (a1) + disp16 (); break;
+ case 14: addr = get_reg (sb) + disp16 (); break;
+ case 15: addr = disp16 (); break;
+ }
+
+ if (destcode < 6)
+ {
+ int d = disp8();
+ sd.mem = 0;
+ sd.mask = 1 << (d & 0x0f);
+ }
+ else
+ {
+ addr &= addr_mask;
+ sd.mem = 1;
+ sd.mask = 1 << (addr & 7);
+ sd.u.addr = addr >> 3;
+ }
+ return sd;
+ }
+
+ srcdest
+ decode_bit11 (int op0)
+ {
+ srcdest sd;
+ sd.mask = 1 << (op0 & 7);
+ sd.mem = 1;
+ sd.u.addr = get_reg (sb) + disp8 ();
+ return sd;
+ }
+
+ int
+ get_bit (srcdest sd)
+ {
+ int b;
+ if (sd.mem)
+ b = mem_get_qi (sd.u.addr) & sd.mask;
+ else
+ b = get_reg (sd.u.reg) & sd.mask;
+ return b ? 1 : 0;
+ }
+
+ void
+ put_bit (srcdest sd, int val)
+ {
+ int b;
+ if (sd.mem)
+ b = mem_get_qi (sd.u.addr);
+ else
+ b = get_reg (sd.u.reg);
+ if (val)
+ b |= sd.mask;
+ else
+ b &= ~sd.mask;
+ if (sd.mem)
+ mem_put_qi (sd.u.addr, b);
+ else
+ put_reg (sd.u.reg, b);
+ }
+
+ int
+ get_bit2 (srcdest sd, int bit)
+ {
+ int b;
+ if (sd.mem)
+ b = mem_get_qi (sd.u.addr + (bit >> 3)) & (1 << (bit & 7));
+ else
+ b = get_reg (sd.u.reg) & (1 << bit);
+ return b ? 1 : 0;
+ }
+
+ void
+ put_bit2 (srcdest sd, int bit, int val)
+ {
+ int b;
+ if (sd.mem)
+ b = mem_get_qi (sd.u.addr + (bit >> 3));
+ else
+ b = get_reg (sd.u.reg);
+ if (val)
+ b |= (1 << (bit & 7));
+ else
+ b &= ~(1 << (bit & 7));
+ if (sd.mem)
+ mem_put_qi (sd.u.addr + (bit >> 3), b);
+ else
+ put_reg (sd.u.reg, b);
+ }
Index: sim/m32c/syscalls.c
===================================================================
RCS file: sim/m32c/syscalls.c
diff -N sim/m32c/syscalls.c
*** sim/m32c/syscalls.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/syscalls.c 6 Oct 2005 22:36:53 -0000
***************
*** 0 ****
--- 1,298 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <sys/time.h>
+
+ #include "gdb/callback.h"
+
+ #include "cpu.h"
+ #include "mem.h"
+ #include "syscalls.h"
+
+ #include "../../libgloss/syscall.h"
+
+ /* The current syscall callbacks we're using. */
+ static struct host_callback_struct *callbacks;
+
+ void
+ set_callbacks (struct host_callback_struct *cb)
+ {
+ callbacks = cb;
+ }
+
+
+ /* A16 ABI: arg1 in r1l (QI) or r1 (HI) or stack
+ arg2 in r2 (HI) or stack
+ arg3..N on stack
+ padding: none
+
+ A24 ABI: arg1 in r0l (QI) or r0 (HI) or stack
+ arg2..N on stack
+ padding: qi->hi
+
+ return value in r0l (QI) r0 (HI) r2r0 (SI)
+ structs: pointer pushed on stack last
+
+ */
+
+ int argp, stackp;
+
+ static int
+ arg(int bytes)
+ {
+ int rv = 0;
+ argp++;
+ if (A16)
+ {
+ switch (argp)
+ {
+ case 1:
+ if (bytes == 1)
+ return get_reg (r1l);
+ if (bytes == 2)
+ return get_reg (r1);
+ break;
+ case 2:
+ if (bytes == 2)
+ return get_reg (r2);
+ break;
+ }
+ }
+ else
+ {
+ switch (argp)
+ {
+ case 1:
+ if (bytes == 1)
+ return get_reg (r0l);
+ if (bytes == 2)
+ return get_reg (r0);
+ break;
+ }
+ }
+ if (bytes == 0)
+ bytes = 2;
+ switch (bytes)
+ {
+ case 1:
+ rv = mem_get_qi (get_reg (sp) + stackp);
+ if (A24)
+ stackp ++;
+ break;
+ case 2:
+ rv = mem_get_hi (get_reg (sp) + stackp);
+ break;
+ case 3:
+ rv = mem_get_psi (get_reg (sp) + stackp);
+ if (A24)
+ stackp ++;
+ break;
+ case 4:
+ rv = mem_get_si (get_reg (sp) + stackp);
+ break;
+ }
+ stackp += bytes;
+ return rv;
+ }
+
+ static void
+ read_target (char *buffer, int address, int count, int asciiz)
+ {
+ char byte;
+ while (count > 0)
+ {
+ byte = mem_get_qi (address++);
+ *buffer++ = byte;
+ if (asciiz && (byte == 0))
+ return;
+ count --;
+ }
+ }
+
+ static void
+ write_target (char *buffer, int address, int count, int asciiz)
+ {
+ char byte;
+ while (count > 0)
+ {
+ byte = *buffer++;
+ mem_put_qi (address++, byte);
+ if (asciiz && (byte == 0))
+ return;
+ count --;
+ }
+ }
+
+ #define PTRSZ (A16 ? 2 : 3)
+
+ static char *callnames[] = {
+ "SYS_zero",
+ "SYS_exit",
+ "SYS_open",
+ "SYS_close",
+ "SYS_read",
+ "SYS_write",
+ "SYS_lseek",
+ "SYS_unlink",
+ "SYS_getpid",
+ "SYS_kill",
+ "SYS_fstat",
+ "SYS_sbrk",
+ "SYS_argvlen",
+ "SYS_argv",
+ "SYS_chdir",
+ "SYS_stat",
+ "SYS_chmod",
+ "SYS_utime",
+ "SYS_time",
+ "SYS_gettimeofday",
+ "SYS_times",
+ "SYS_link"
+ };
+
+ void
+ m32c_syscall (int id)
+ {
+ static char buf[256];
+ int rv;
+
+ argp = 0;
+ stackp = A16 ? 3 : 4;
+ if (trace)
+ printf("\033[31m/* SYSCALL(%d) = %s */\033[0m\n", id, callnames[id]);
+ switch (id)
+ {
+ case SYS_exit:
+ {
+ int ec = arg(2);
+ if (verbose)
+ printf("[exit %d]\n", ec);
+ step_result = M32C_MAKE_EXITED (ec);
+ }
+ break;
+
+ case SYS_open:
+ {
+ int path = arg(PTRSZ);
+ int oflags = arg(2);
+ int cflags = arg(2);
+
+ read_target (buf, path, 256, 1);
+ if (trace) printf("open(\"%s\",0x%x,%#o) = ", buf, oflags, cflags);
+
+ if (callbacks)
+ /* The callback vector ignores CFLAGS. */
+ rv = callbacks->open (callbacks, buf, oflags);
+ else
+ {
+ int h_oflags = 0;
+
+ if (oflags & 0x0001) h_oflags |= O_WRONLY;
+ if (oflags & 0x0002) h_oflags |= O_RDWR;
+ if (oflags & 0x0200) h_oflags |= O_CREAT;
+ if (oflags & 0x0008) h_oflags |= O_APPEND;
+ if (oflags & 0x0400) h_oflags |= O_TRUNC;
+ rv = open (buf, h_oflags, cflags);
+ }
+ if (trace) printf("%d\n", rv);
+ put_reg (r0, rv);
+ }
+ break;
+
+ case SYS_close:
+ {
+ int fd = arg(2);
+
+ if (callbacks)
+ rv = callbacks->close(callbacks, fd);
+ else if (fd > 2)
+ rv = close(fd);
+ else
+ rv = 0;
+ if (trace) printf("close(%d) = %d\n", fd, rv);
+ put_reg (r0, rv);
+ }
+ break;
+
+ case SYS_read:
+ {
+ int fd = arg(2);
+ int addr = arg(PTRSZ);
+ int count = arg(2);
+
+ if (count > sizeof(buf))
+ count = sizeof(buf);
+ if (callbacks)
+ rv = callbacks->read (callbacks, fd, buf, count);
+ else
+ rv = read (fd, buf, count);
+ if (trace) printf("read(%d,%d) = %d\n", fd, count, rv);
+ if (rv > 0)
+ write_target (buf, addr, rv, 0);
+ put_reg (r0, rv);
+ }
+ break;
+
+ case SYS_write:
+ {
+ int fd = arg(2);
+ int addr = arg(PTRSZ);
+ int count = arg(2);
+
+ if (count > sizeof(buf))
+ count = sizeof(buf);
+ if (trace) printf("write(%d,0x%x,%d)\n", fd, addr, count);
+ read_target (buf, addr, count, 0);
+ if (trace) fflush(stdout);
+ if (callbacks)
+ rv = callbacks->write (callbacks, fd, buf, count);
+ else
+ rv = write (fd, buf, count);
+ if (trace) printf("write(%d,%d) = %d\n", fd, count, rv);
+ put_reg (r0, rv);
+ }
+ break;
+
+ case SYS_getpid:
+ put_reg (r0, 42);
+ break;
+
+ case SYS_gettimeofday:
+ {
+ int tvaddr = arg(PTRSZ);
+ struct timeval tv;
+
+ rv = gettimeofday (&tv, 0);
+ if (trace) printf("gettimeofday: %ld sec %ld usec to 0x%x\n", tv.tv_sec, tv.tv_usec, tvaddr);
+ mem_put_si (tvaddr, tv.tv_sec);
+ mem_put_si (tvaddr+4, tv.tv_usec);
+ put_reg (r0, rv);
+ }
+ break;
+
+ case SYS_kill:
+ {
+ int pid = arg(2);
+ int sig = arg(2);
+ if (pid == 42)
+ {
+ if (verbose)
+ printf("[signal %d]\n", sig);
+ step_result = M32C_MAKE_STOPPED (sig);
+ }
+ }
+ break;
+
+ case 11:
+ {
+ int heaptop_arg = arg(PTRSZ);
+ if (trace) printf("sbrk: heap top set to %x\n", heaptop_arg);
+ heaptop = heaptop_arg;
+ if (heapbottom == 0)
+ heapbottom = heaptop_arg;
+ }
+ break;
+
+ }
+ }
Index: sim/m32c/syscalls.h
===================================================================
RCS file: sim/m32c/syscalls.h
diff -N sim/m32c/syscalls.h
*** sim/m32c/syscalls.h 1 Jan 1970 00:00:00 -0000
--- sim/m32c/syscalls.h 6 Oct 2005 22:36:53 -0000
***************
*** 0 ****
--- 1,3 ----
+ struct host_callback_struct;
+ extern void set_callbacks (struct host_callback_struct *);
+ extern void m32c_syscall (int id);
Index: sim/m32c/trace.c
===================================================================
RCS file: sim/m32c/trace.c
diff -N sim/m32c/trace.c
*** sim/m32c/trace.c 1 Jan 1970 00:00:00 -0000
--- sim/m32c/trace.c 6 Oct 2005 22:36:53 -0000
***************
*** 0 ****
--- 1,280 ----
+ #include <stdio.h>
+ #include <stdarg.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <ctype.h>
+
+ #include "bfd.h"
+ #include "dis-asm.h"
+ #include "m32c-desc.h"
+
+ #include "cpu.h"
+ #include "mem.h"
+ #include "load.h"
+
+ static int
+ sim_dis_read (bfd_vma memaddr, bfd_byte *ptr, unsigned int length, struct disassemble_info *info)
+ {
+ mem_get_blk (memaddr, ptr, length);
+ return 0;
+ }
+
+ /* Filter out (in place) symbols that are useless for disassembly.
+ COUNT is the number of elements in SYMBOLS.
+ Return the number of useful symbols. */
+
+ static long
+ remove_useless_symbols (asymbol **symbols, long count)
+ {
+ register asymbol **in_ptr = symbols, **out_ptr = symbols;
+
+ while (--count >= 0)
+ {
+ asymbol *sym = *in_ptr++;
+
+ if (strstr(sym->name, "gcc2_compiled"))
+ continue;
+ if (sym->name == NULL || sym->name[0] == '\0')
+ continue;
+ if (sym->flags & (BSF_DEBUGGING))
+ continue;
+ if (bfd_is_und_section (sym->section)
+ || bfd_is_com_section (sym->section))
+ continue;
+
+ *out_ptr++ = sym;
+ }
+ return out_ptr - symbols;
+ }
+
+ static int
+ compare_symbols (const PTR ap, const PTR bp)
+ {
+ const asymbol *a = *(const asymbol **)ap;
+ const asymbol *b = *(const asymbol **)bp;
+
+ if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
+ return 1;
+ else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
+ return -1;
+ return 0;
+ }
+
+ static char opbuf[1000];
+
+ static int
+ op_printf(char *buf, char *fmt, ...)
+ {
+ int ret;
+ va_list ap;
+
+ va_start (ap, fmt);
+ ret = vsprintf (opbuf+strlen(opbuf), fmt, ap);
+ va_end (ap);
+ return ret;
+ }
+
+ static bfd *current_bfd;
+
+ void
+ sim_disasm_init(bfd *prog)
+ {
+ current_bfd = prog;
+ }
+
+ typedef struct Files {
+ struct Files *next;
+ char *filename;
+ int nlines;
+ char **lines;
+ char *data;
+ } Files;
+ Files *files = 0;
+
+ static char *
+ load_file_and_line (const char *filename, int lineno)
+ {
+ Files *f;
+ for (f=files; f; f=f->next)
+ if (strcmp (f->filename, filename) == 0)
+ break;
+ if (!f)
+ {
+ int i;
+ struct stat s;
+ const char *found_filename, *slash;
+
+ found_filename = filename;
+ while (1)
+ {
+ if (stat (found_filename, &s) == 0)
+ break;
+ slash = strchr(found_filename, '/');
+ if (!slash)
+ return "";
+ found_filename = slash + 1;
+ }
+
+ f = (Files *)malloc(sizeof(Files));
+ f->next = files;
+ files = f;
+ f->filename = strdup (filename);
+ f->data = (char *)malloc (s.st_size + 2);
+ FILE *file = fopen(found_filename, "rb");
+ fread (f->data, 1, s.st_size, file);
+ f->data[s.st_size] = 0;
+ fclose(file);
+
+ f->nlines = 1;
+ for (i=0; i<s.st_size; i++)
+ if (f->data[i] == '\n')
+ f->nlines ++;
+ f->lines = (char **)malloc (f->nlines * sizeof(char *));
+ f->lines[0] = f->data;
+ f->nlines = 1;
+ for (i=0; i<s.st_size; i++)
+ if (f->data[i] == '\n')
+ {
+ f->lines[f->nlines] = f->data+i+1;
+ while (*f->lines[f->nlines] == ' '
+ || *f->lines[f->nlines] == '\t')
+ f->lines[f->nlines]++;
+ f->nlines++;
+ f->data[i] = 0;
+ }
+ }
+ if (lineno < 1 || lineno > f->nlines)
+ return "";
+ return f->lines[lineno-1];
+ }
+
+ void
+ sim_disasm_one()
+ {
+ static int initted = 0;
+ static asymbol **symtab = 0;
+ static int symcount = 0;
+ static int last_sym = -1;
+ static struct disassemble_info info;
+ int storage, sym, bestaddr;
+ int min, max, i;
+ static asection *code_section = 0;
+ static bfd_vma code_base = 0;
+ asection *s;
+ int save_trace = trace;
+
+ static const char *prev_filename = "";
+ static int prev_lineno = 0;
+ const char *filename;
+ const char *functionname;
+ unsigned int lineno;
+
+ int mypc = get_reg (pc);
+
+ if (current_bfd == 0)
+ return;
+
+ trace = 0;
+
+ if (!initted)
+ {
+ initted = 1;
+ memset(&info, 0, sizeof(info));
+ INIT_DISASSEMBLE_INFO(info, stdout, op_printf);
+ info.read_memory_func = sim_dis_read;
+ info.arch = bfd_get_arch (current_bfd);
+ info.mach = bfd_get_mach (current_bfd);
+ if (info.mach == 0)
+ {
+ info.arch = bfd_arch_m32c;
+ info.mach = default_machine;
+ }
+ disassemble_init_for_target (&info);
+
+ storage = bfd_get_symtab_upper_bound (current_bfd);
+ if (storage > 0)
+ {
+ symtab = (asymbol **) malloc (storage);
+ symcount = bfd_canonicalize_symtab (current_bfd, symtab);
+ symcount = remove_useless_symbols (symtab, symcount);
+ qsort (symtab, symcount, sizeof(asymbol *), compare_symbols);
+ }
+ for (s = current_bfd->sections; s; s = s->next)
+ {
+ if (s->flags & SEC_CODE || code_section == 0)
+ {
+ code_section = s;
+ code_base = bfd_section_lma (current_bfd, s);
+ break;
+ }
+ }
+ }
+
+ filename = functionname = 0;
+ lineno = 0;
+ if (bfd_find_nearest_line (current_bfd, code_section, symtab, mypc - code_base,
+ &filename, &functionname, &lineno))
+ {
+ if (filename && functionname && lineno)
+ {
+ if (lineno != prev_lineno || strcmp (prev_filename, filename))
+ {
+ char *the_line = load_file_and_line (filename, lineno);
+ const char *slash = strrchr (filename, '/');
+ if (!slash) slash = filename; else slash++;
+ printf("=============================================================================\n");
+ printf("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n", slash, lineno, the_line);
+ }
+ prev_lineno = lineno;
+ prev_filename = filename;
+ }
+ }
+
+ {
+ min = -1; max = symcount;
+ while (min < max-1) {
+ bfd_vma sa;
+ sym = (min+max)/2;
+ sa = bfd_asymbol_value (symtab[sym]);
+ /*printf("checking %4d %08x %s\n", sym, sa, bfd_asymbol_name (symtab[sym]));*/
+ if (sa > mypc)
+ max = sym;
+ else if (sa < mypc)
+ min = sym;
+ else
+ {
+ min = sym;
+ break;
+ }
+ }
+ if (min != -1 && min != last_sym)
+ {
+ bestaddr = bfd_asymbol_value (symtab[min]);
+ printf("\033[43;30m%s", bfd_asymbol_name (symtab[min]));
+ if (bestaddr != mypc)
+ printf("+%d", mypc-bestaddr);
+ printf(":\t\t\t\033[0m\n");
+ last_sym = min;
+ #if 0
+ if (trace == 1)
+ if (strcmp(bfd_asymbol_name (symtab[min]), "abort") == 0
+ || strcmp(bfd_asymbol_name (symtab[min]), "exit") == 0)
+ trace = 0;
+ #endif
+ }
+ }
+
+ opbuf[0] = 0;
+ printf("\033[33m%06x: ", mypc);
+ max = print_insn_m32c(mypc, &info);
+ for (i=0; i<max; i++)
+ printf("%02x", mem_get_qi(mypc+i));
+ for (; i<6; i++)
+ printf(" ");
+ printf("%-16s ", opbuf);
+
+ printf("\033[0m\n");
+ trace = save_trace;
+ }
Index: sim/m32c/trace.h
===================================================================
RCS file: sim/m32c/trace.h
diff -N sim/m32c/trace.h
*** sim/m32c/trace.h 1 Jan 1970 00:00:00 -0000
--- sim/m32c/trace.h 6 Oct 2005 22:36:53 -0000
***************
*** 0 ****
--- 1,2 ----
+ void sim_disasm_init(bfd *prog);
+ extern void sim_disasm_one (void);
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
2005-10-07 20:46 RFA: contribute Renesas M32C sim Jim Blandy
@ 2005-10-07 21:03 ` Daniel Jacobowitz
2005-10-09 0:29 ` Jim Blandy
2005-10-09 20:15 ` Daniel Jacobowitz
2005-10-15 12:06 ` Eli Zaretskii
2 siblings, 1 reply; 14+ messages in thread
From: Daniel Jacobowitz @ 2005-10-07 21:03 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
On Fri, Oct 07, 2005 at 01:44:09PM -0700, Jim Blandy wrote:
>
> DJ Delorie is the target maintainer for the M32C, so the rules in
> sim/MAINTAINERS make him the maintainer of this sim by default.
GDB does not contain an m32c port, and DJ is only listed for DJGPP in
gdb/MAINTAINERS. So I don't see how that can be true. He's only
listed for m32c in newlib.
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
2005-10-07 21:03 ` Daniel Jacobowitz
@ 2005-10-09 0:29 ` Jim Blandy
0 siblings, 0 replies; 14+ messages in thread
From: Jim Blandy @ 2005-10-09 0:29 UTC (permalink / raw)
To: gdb-patches
Daniel Jacobowitz <drow@false.org> writes:
> On Fri, Oct 07, 2005 at 01:44:09PM -0700, Jim Blandy wrote:
>>
>> DJ Delorie is the target maintainer for the M32C, so the rules in
>> sim/MAINTAINERS make him the maintainer of this sim by default.
>
> GDB does not contain an m32c port, and DJ is only listed for DJGPP in
> gdb/MAINTAINERS. So I don't see how that can be true. He's only
> listed for m32c in newlib.
... I was confused. sim/MAINTAINERS is clear, but I misread it.
DJ Delorie has volunteered to maintain the m32c sim; he is its author.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
2005-10-07 20:46 RFA: contribute Renesas M32C sim Jim Blandy
2005-10-07 21:03 ` Daniel Jacobowitz
@ 2005-10-09 20:15 ` Daniel Jacobowitz
2005-10-12 18:21 ` Jim Blandy
2005-10-12 22:12 ` Jim Blandy
2005-10-15 12:06 ` Eli Zaretskii
2 siblings, 2 replies; 14+ messages in thread
From: Daniel Jacobowitz @ 2005-10-09 20:15 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
There's a limit to how useful I can be reviewing sim patches, but I'll
try.
The most glaring omission is copyright notices. Not a single one.
Pretty much every file should have one. I assume the intention is to
assign this contribution to the FSF.
There seem to be a lot of too-long lines.
> + void
> + prefix (src_allowed, dest_allowed, index_bytewidth)
> + {
> + }
And what's that for?
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
2005-10-09 20:15 ` Daniel Jacobowitz
@ 2005-10-12 18:21 ` Jim Blandy
[not found] ` <jimb@redhat.com>
2005-10-12 22:12 ` Jim Blandy
1 sibling, 1 reply; 14+ messages in thread
From: Jim Blandy @ 2005-10-12 18:21 UTC (permalink / raw)
To: gdb-patches
Daniel Jacobowitz <drow@false.org> writes:
> The most glaring omission is copyright notices. Not a single one.
> Pretty much every file should have one. I assume the intention is to
> assign this contribution to the FSF.
My face is red. Of course there should be copyright notices.
> There seem to be a lot of too-long lines.
I'll address those.
>> + void
>> + prefix (src_allowed, dest_allowed, index_bytewidth)
>> + {
>> + }
>
> And what's that for?
I don't know. I thought it was some sort of annotation for opc2c to
consume, but that doesn't seem to be so. I'll find out.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
2005-10-09 20:15 ` Daniel Jacobowitz
2005-10-12 18:21 ` Jim Blandy
@ 2005-10-12 22:12 ` Jim Blandy
2006-01-23 2:03 ` Daniel Jacobowitz
1 sibling, 1 reply; 14+ messages in thread
From: Jim Blandy @ 2005-10-12 22:12 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 211 bytes --]
I think the attached patch should address the points you raised:
- I added copyright notices.
- I ran the code through gdb_indent.sh, and fixed up some further messes.
- I added a comment to m32c.opc:prefix.
[-- Attachment #2: Patch to add Renesas M32C sim to GDB tree --]
[-- Type: application/x-gzip, Size: 41707 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
2005-10-07 20:46 RFA: contribute Renesas M32C sim Jim Blandy
2005-10-07 21:03 ` Daniel Jacobowitz
2005-10-09 20:15 ` Daniel Jacobowitz
@ 2005-10-15 12:06 ` Eli Zaretskii
2005-10-17 23:26 ` Jim Blandy
2 siblings, 1 reply; 14+ messages in thread
From: Eli Zaretskii @ 2005-10-15 12:06 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
> From: Jim Blandy <jimb@redhat.com>
> Date: Fri, 07 Oct 2005 13:44:09 -0700
>
> DJ Delorie is the target maintainer for the M32C, so the rules in
> sim/MAINTAINERS make him the maintainer of this sim by default.
>
> sim/ChangeLog:
> 2005-10-06 Jim Blandy <jimb@redhat.com>
>
> Add simulator for Renesas M32C and M16C.
>
> * m32c: New directory.
> * configure.ac: Add entry for Renesas M32C.
> * configure: Regenerate.
Please make sure to add a notice about this new simulator to gdb/NEWS.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
2005-10-15 12:06 ` Eli Zaretskii
@ 2005-10-17 23:26 ` Jim Blandy
0 siblings, 0 replies; 14+ messages in thread
From: Jim Blandy @ 2005-10-17 23:26 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Jim Blandy <jimb@redhat.com>
>> Date: Fri, 07 Oct 2005 13:44:09 -0700
>>
>> DJ Delorie is the target maintainer for the M32C, so the rules in
>> sim/MAINTAINERS make him the maintainer of this sim by default.
>>
>> sim/ChangeLog:
>> 2005-10-06 Jim Blandy <jimb@redhat.com>
>>
>> Add simulator for Renesas M32C and M16C.
>>
>> * m32c: New directory.
>> * configure.ac: Add entry for Renesas M32C.
>> * configure: Regenerate.
>
> Please make sure to add a notice about this new simulator to gdb/NEWS.
Yes --- thanks for reminding me of that. I've added:
* New simulators
Renesas M32C / M16C m32c-elf
I appreciate Daniel's read-over. Is someone willing to sign off on
the revised sim?
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
[not found] ` <jimb@redhat.com>
@ 2005-12-14 18:40 ` DJ Delorie
2005-12-15 0:01 ` Daniel Jacobowitz
0 siblings, 1 reply; 14+ messages in thread
From: DJ Delorie @ 2005-12-14 18:40 UTC (permalink / raw)
To: gdb-patches
> >> + void
> >> + prefix (src_allowed, dest_allowed, index_bytewidth)
> >> + {
> >> + }
> >
> > And what's that for?
>
> I don't know. I thought it was some sort of annotation for opc2c to
> consume, but that doesn't seem to be so. I'll find out.
I remember talking to Jim about this, but I don't see him answering in
the mail archives, and since I was checking on the m32c/gdb status I
figured I'd at least get this one answered.
In short, that function exists so it can be called, it's the callers
that are important at the moment.
The callers act as documentation for what prefixes and indexes are
permitted for each opcode. As I was going through the tedious process
of implementing each opcode, I added all the calls to prefix() with
the correct arguments. The function does nothing yet, but at some
point in the future it may fault if prefixes are used where the real
chip doesn't support them.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
2005-12-14 18:40 ` DJ Delorie
@ 2005-12-15 0:01 ` Daniel Jacobowitz
2005-12-15 14:48 ` Jim Blandy
0 siblings, 1 reply; 14+ messages in thread
From: Daniel Jacobowitz @ 2005-12-15 0:01 UTC (permalink / raw)
To: gdb-patches
On Tue, Dec 13, 2005 at 05:43:06PM -0500, DJ Delorie wrote:
>
> > >> + void
> > >> + prefix (src_allowed, dest_allowed, index_bytewidth)
> > >> + {
> > >> + }
> > >
> > > And what's that for?
> >
> > I don't know. I thought it was some sort of annotation for opc2c to
> > consume, but that doesn't seem to be so. I'll find out.
>
> I remember talking to Jim about this, but I don't see him answering in
> the mail archives, and since I was checking on the m32c/gdb status I
> figured I'd at least get this one answered.
>
> In short, that function exists so it can be called, it's the callers
> that are important at the moment.
>
> The callers act as documentation for what prefixes and indexes are
> permitted for each opcode. As I was going through the tedious process
> of implementing each opcode, I added all the calls to prefix() with
> the correct arguments. The function does nothing yet, but at some
> point in the future it may fault if prefixes are used where the real
> chip doesn't support them.
Then please add some useful information there, so that the next
reviewer through the code does not remove it :-)
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
2005-12-15 0:01 ` Daniel Jacobowitz
@ 2005-12-15 14:48 ` Jim Blandy
2005-12-15 16:18 ` Daniel Jacobowitz
0 siblings, 1 reply; 14+ messages in thread
From: Jim Blandy @ 2005-12-15 14:48 UTC (permalink / raw)
To: gdb-patches
The (unposted) code I've got currently reads:
/* Indicate which sorts of prefixes are allowed for the current
opcode. */
void
prefix (src_allowed, dest_allowed, index_bytewidth)
{
/* At the moment, we don't do anything with this information. We
just wanted to get the information entered in some
machine-readable form while we were going through all the
opcodes. */
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
2005-12-15 14:48 ` Jim Blandy
@ 2005-12-15 16:18 ` Daniel Jacobowitz
0 siblings, 0 replies; 14+ messages in thread
From: Daniel Jacobowitz @ 2005-12-15 16:18 UTC (permalink / raw)
To: gdb-patches
On Tue, Dec 13, 2005 at 04:39:54PM -0800, Jim Blandy wrote:
> The (unposted) code I've got currently reads:
>
> /* Indicate which sorts of prefixes are allowed for the current
> opcode. */
> void
> prefix (src_allowed, dest_allowed, index_bytewidth)
> {
> /* At the moment, we don't do anything with this information. We
> just wanted to get the information entered in some
> machine-readable form while we were going through all the
> opcodes. */
> }
Perfect :-)
--
Daniel Jacobowitz
CodeSourcery, LLC
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
2005-10-12 22:12 ` Jim Blandy
@ 2006-01-23 2:03 ` Daniel Jacobowitz
2006-01-23 22:11 ` Jim Blandy
0 siblings, 1 reply; 14+ messages in thread
From: Daniel Jacobowitz @ 2006-01-23 2:03 UTC (permalink / raw)
To: gdb-patches
On Wed, Oct 12, 2005 at 03:12:22PM -0700, Jim Blandy wrote:
>
> I think the attached patch should address the points you raised:
>
> - I added copyright notices.
> - I ran the code through gdb_indent.sh, and fixed up some further messes.
> - I added a comment to m32c.opc:prefix.
Hi Jim,
Anything ever come of this? I don't see a reason to hold off on the
revised patch.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFA: contribute Renesas M32C sim
2006-01-23 2:03 ` Daniel Jacobowitz
@ 2006-01-23 22:11 ` Jim Blandy
0 siblings, 0 replies; 14+ messages in thread
From: Jim Blandy @ 2006-01-23 22:11 UTC (permalink / raw)
To: gdb-patches
On 1/22/06, Daniel Jacobowitz <drow@false.org> wrote:
> Anything ever come of this? I don't see a reason to hold off on the
> revised patch.
I've committed the revised patch. Thanks for the reminder.
For the GDB port, I still need to rework the prologue analyzer as you suggested.
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2006-01-23 22:11 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-10-07 20:46 RFA: contribute Renesas M32C sim Jim Blandy
2005-10-07 21:03 ` Daniel Jacobowitz
2005-10-09 0:29 ` Jim Blandy
2005-10-09 20:15 ` Daniel Jacobowitz
2005-10-12 18:21 ` Jim Blandy
[not found] ` <jimb@redhat.com>
2005-12-14 18:40 ` DJ Delorie
2005-12-15 0:01 ` Daniel Jacobowitz
2005-12-15 14:48 ` Jim Blandy
2005-12-15 16:18 ` Daniel Jacobowitz
2005-10-12 22:12 ` Jim Blandy
2006-01-23 2:03 ` Daniel Jacobowitz
2006-01-23 22:11 ` Jim Blandy
2005-10-15 12:06 ` Eli Zaretskii
2005-10-17 23:26 ` Jim Blandy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox