From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20575 invoked by alias); 7 Oct 2005 20:46:41 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 20516 invoked by uid 22791); 7 Oct 2005 20:46:11 -0000 Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Fri, 07 Oct 2005 20:46:11 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.11/8.12.11) with ESMTP id j97Kk9wC026420 for ; Fri, 7 Oct 2005 16:46:09 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id j97Kk8V31846; Fri, 7 Oct 2005 16:46:08 -0400 Received: from alligator.red-bean.com.redhat.com (vpn26-17.sfbay.redhat.com [172.16.26.17]) by devserv.devel.redhat.com (8.12.11/8.12.11) with ESMTP id j97Kk0Eg005417; Fri, 7 Oct 2005 16:46:01 -0400 To: gdb-patches@sourceware.org Subject: RFA: contribute Renesas M32C sim From: Jim Blandy Date: Fri, 07 Oct 2005 20:46:00 -0000 Message-ID: User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-SW-Source: 2005-10/txt/msg00061.txt.bz2 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 =09 Add simulator for Renesas M32C and M16C. =09 * m32c: New directory. * configure.ac: Add entry for Renesas M32C. * configure: Regenerate. sim/m32c/ChangeLog: 2005-10-06 Jim Blandy Simulator for Renesas M32C and M16C, by DJ Delorie , with further work from Jim Blandy and Kevin Buettner . =09 * 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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}" !=3D no; then *** 73,78 **** --- 73,82 ---- testsuite=3Dyes common=3Dyes ;; + m32c-*-*) + AC_CONFIG_SUBDIRS(m32c) + common=3Dyes + ;; m32r-*-*) AC_CONFIG_SUBDIRS(m32r) testsuite=3Dyes Index: sim/m32c/Makefile.in =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 ---- +=20 + ## COMMON_PRE_CONFIG_FRAG +=20 + SIM_EXTRA_CFLAGS =3D -Wall +=20 + SIM_RUN_OBJS =3D \ + main.o \ + $(ENDLIST) +=20 + SIM_OBJS =3D \ + gdb-if.o \ + int.o \ + load.o \ + mem.o \ + misc.o \ + reg.o \ + r8c.o \ + m32c.o \ + srcdest.o \ + syscalls.o \ + trace.o \ + $(ENDLIST) +=20 + # SIM_EXTRA_ALL =3D sample.x sample2.x +=20 + LIBS =3D $B/bfd/libbfd.a $B/libiberty/libiberty.a +=20 + ## COMMON_POST_CONFIG_FRAG +=20 + arch =3D m32c +=20 + r8c.c : r8c.opc opc2c + ./opc2c -l r8c.out $(srcdir)/r8c.opc > r8c.c +=20 + m32c.c : m32c.opc opc2c + ./opc2c -l m32c.out $(srcdir)/m32c.opc > m32c.c +=20 + opc2c : opc2c.o safe-fgets.o + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ +=20 + 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 +=20 + sample.mot : sample.x + ../../binutils/objcopy --srec-forceS3 -O srec sample.x sample.mot +=20 + sample2.x : sample2.o gloss.o $(srcdir)/sample.ld + ../../ld/ld-new sample2.o gloss.o -o sample2.x -T$(srcdir)/sample.ld +=20 + sample2.o : $(srcdir)/sample2.c + ../../gcc/xgcc $(CPUFLAGS) -B../../gcc/ -c $(srcdir)/sample2.c -o sample= 2.o +=20 + gloss.o : $(srcdir)/gloss.S + ../../gcc/xgcc $(CPUFLAGS) -B../../gcc/ -c $(srcdir)/gloss.S -o gloss.o +=20 + encodings: + grep '/\* [01]' $(srcdir)/r8c.opc | sort +=20 + 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 +=20 + r8c.o : cpu.h mem.h misc.h int.h Index: sim/m32c/blinky.S =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 +=20 + .global _start + _start: + mov.w #0xe1,a0 + top: + sub.w #1,r0 + mov.b r0h,[a0] +=20 + mov.w #1000,r1 + loop: + adjnz.w #-1,r1,loop +=20 + jmp.w top Index: sim/m32c/config.in =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: sim/m32c/config.in diff -N sim/m32c/config.in Index: sim/m32c/configure.in =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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) +=20 + sinclude(../common/aclocal.m4) +=20 + # 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) +=20 + SIM_AC_OUTPUT Index: sim/m32c/cpu.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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; +=20 + typedef unsigned char QI; + typedef unsigned short HI; + typedef unsigned long SI; + typedef unsigned long long DI; +=20 + #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); +=20 + #define A16 (m32c_cpu & 0x10) + #define A24 (m32c_cpu & 0x20) +=20 + 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; +=20 + 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; +=20 + extern regs_type regs; + extern int addr_mask; + extern int membus_mask; +=20 + #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 +=20 + #define REG_BANK (regs.r_flags & FLAG_B ? 1 : 0) +=20 + 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; +=20 + extern char *reg_names[]; + extern int reg_bytes[]; +=20 + extern unsigned int b2mask[]; + extern unsigned int b2signbit[]; + extern int b2maxsigned[]; + extern int b2minsigned[]; +=20 + 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); +=20 + 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); +=20 + const char *bits(int v, int b); +=20 + typedef struct { + QI bytes; + QI mem; + HI mask; + union { + unsigned int addr; + reg_id reg; + } u; + } srcdest; +=20 + void decode_indirect (int src_indirect, int dest_indirect); + void decode_index (int src_addend, int dest_addend); +=20 + /* 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 +=20 + /* 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); +=20 + srcdest widen_sd (srcdest sd); + srcdest reg_sd (reg_id reg); +=20 + /* 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); +=20 + int get_src (srcdest sd); + void put_dest (srcdest sd, int value); +=20 + int condition_true (int cond_id); +=20 + #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) +=20 + /* 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. +=20 + 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) +=20 + #define M32C_STEPPED(r) ((r) =3D=3D M32C_MAKE_STEPPED ()) + #define M32C_HIT_BREAK(r) ((r) =3D=3D M32C_MAKE_HIT_BREAK ()) + #define M32C_EXITED(r) (((r) & 0xff) =3D=3D 2) + #define M32C_EXIT_STATUS(r) ((r) >> 8) + #define M32C_STOPPED(r) (((r) & 0xff) =3D=3D 3) + #define M32C_STOP_SIG(r) ((r) >> 8) +=20 + /* The step result for the current step. Global to allow + communication between the stepping function and the system + calls. */ + extern int step_result; +=20 + /* Used to detect heap/stack collisions */ + extern unsigned int heaptop; + extern unsigned int heapbottom; +=20 + /* Points to one of the below functions, set by m32c_load(). */ + extern int (*decode_opcode)(); +=20 + extern int decode_r8c(); + extern int decode_m32c(); +=20 + extern void trace_register_changes (); Index: sim/m32c/gdb-if.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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. */ +=20 + #include + #include + #include + #include + #include +=20 + #include "ansidecl.h" + #include "gdb/callback.h" + #include "gdb/remote-sim.h" + #include "gdb/signals.h" + #include "gdb/sim-m32c.h" +=20 + #include "cpu.h" + #include "mem.h" + #include "load.h" + #include "syscalls.h" +=20 + /* 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. +=20 + 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; + }; +=20 + static struct sim_state the_minisim =3D { + "This is the sole m32c minisim instance. See libsim.a's global variabl= es." + }; +=20 + static int open; +=20 + SIM_DESC=20 + 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"); +=20 + /* The 'run' interface doesn't use this function, so we don't care + about KIND; it's always SIM_OPEN_DEBUG. */ + if (kind !=3D SIM_OPEN_DEBUG) + fprintf (stderr, "m32c minisim: sim_open KIND !=3D SIM_OPEN_DEBUG: %d= \n", + kind); +=20 + if (abfd) + m32c_set_mach (bfd_get_mach (abfd)); +=20 + /* We can use ABFD, if non-NULL to select the appropriate + architecture. But we only support the r8c right now. */ +=20 + set_callbacks (callback); +=20 + /* We don't expect any command-line arguments. */ +=20 + init_mem (); + init_regs (); +=20 + open =3D 1; + return &the_minisim; + } +=20 + static void + check_desc (SIM_DESC sd) + { + if (sd !=3D &the_minisim) + fprintf (stderr, "m32c minisim: desc !=3D &the_minisim\n"); + } +=20 + void + sim_close (SIM_DESC sd, int quitting) + { + check_desc (sd); +=20 + /* Not much to do. At least free up our memory. */ + init_mem (); +=20=20=20 + open =3D 0; + } +=20 + static bfd * + open_objfile (const char *filename) + { + bfd *prog =3D bfd_openr (filename, 0); +=20 + if (! prog) + { + fprintf (stderr, "Can't read %s\n", filename); + return 0; + } +=20 + if (! bfd_check_format (prog, bfd_object)) + { + fprintf (stderr, "%s not a m32c program\n", filename); + return 0; + } +=20 + return prog; + } +=20 +=20 + SIM_RC + sim_load (SIM_DESC sd, char *prog, struct bfd *abfd, int from_tty) + { + check_desc (sd); +=20 + if (! abfd) + abfd =3D open_objfile (prog); + if (! abfd) + return SIM_RC_FAIL; +=20 + m32c_load (abfd); +=20 + return SIM_RC_OK; + } +=20 + SIM_RC + sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **e= nv) + { + check_desc (sd); +=20 + if (abfd) + m32c_load (abfd); +=20 + return SIM_RC_OK; + } +=20 + int + sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length) + { + check_desc (sd); +=20 + if (mem =3D=3D 0) + return 0; +=20 + mem_get_blk ((int) mem, buf, length); +=20 + return length; + } +=20 + int + sim_write (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length) + { + check_desc (sd); +=20 + mem_put_blk ((int) mem, buf, length); +=20 + return length; + } +=20 +=20 + /* Read the LENGTH bytes at BUF as an little-endian value. */ + static DI + get_le (unsigned char *buf, int length) + { + DI acc =3D 0; + while (--length >=3D 0) + acc =3D (acc << 8) + buf[length]; +=20 + return acc; + } +=20 + /* 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; +=20 + for (i =3D 0; i < length; i++) + { + buf[i] =3D val & 0xff; + val >>=3D 8; + } + } +=20 + static int + check_regno (enum m32c_sim_reg regno) + { + return 0 <=3D regno && regno < m32c_sim_reg_num_regs; + } +=20 + 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); + } + } +=20 + static size_t + reg_size (enum m32c_sim_reg regno) + { + switch (regno) + { + case m32c_sim_reg_r0_bank0:=09=09 + case m32c_sim_reg_r1_bank0:=09=09 + case m32c_sim_reg_r2_bank0:=09=09 + case m32c_sim_reg_r3_bank0:=09=09 + 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; +=20 + case m32c_sim_reg_a0_bank0:=20=20=20=20=20=20=20=20=20 + case m32c_sim_reg_a1_bank0:=09=09 + case m32c_sim_reg_fb_bank0:=09=09 + case m32c_sim_reg_sb_bank0:=09=09 + 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); +=20 + 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); +=20 + case m32c_sim_reg_dmd0: + case m32c_sim_reg_dmd1: + return 1; +=20 + case m32c_sim_reg_dct0: + case m32c_sim_reg_dct1: + case m32c_sim_reg_drc0: + case m32c_sim_reg_drc1: + return 2; +=20 + 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; +=20 + default: + fprintf (stderr, "m32c minisim: unrecognized register number: %d\n", + regno); + return -1; + } + } +=20 + int + sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf, int lengt= h) + { + size_t size; +=20 + check_desc (sd); +=20 + if (! check_regno (regno)) + return 0; +=20 + size =3D reg_size (regno); + if (length =3D=3D size) + { + DI val; +=20 + switch (regno) + { + case m32c_sim_reg_r0_bank0: val =3D regs.r[0].r_r0; break; + case m32c_sim_reg_r1_bank0: val =3D regs.r[0].r_r1; break; + case m32c_sim_reg_r2_bank0: val =3D regs.r[0].r_r2; break; + case m32c_sim_reg_r3_bank0: val =3D regs.r[0].r_r3; break; + case m32c_sim_reg_a0_bank0: val =3D regs.r[0].r_a0; break; + case m32c_sim_reg_a1_bank0: val =3D regs.r[0].r_a1; break; + case m32c_sim_reg_fb_bank0: val =3D regs.r[0].r_fb; break; + case m32c_sim_reg_sb_bank0: val =3D regs.r[0].r_sb; break; + case m32c_sim_reg_r0_bank1: val =3D regs.r[1].r_r0; break; + case m32c_sim_reg_r1_bank1: val =3D regs.r[1].r_r1; break; + case m32c_sim_reg_r2_bank1: val =3D regs.r[1].r_r2; break; + case m32c_sim_reg_r3_bank1: val =3D regs.r[1].r_r3; break; + case m32c_sim_reg_a0_bank1: val =3D regs.r[1].r_a0; break; + case m32c_sim_reg_a1_bank1: val =3D regs.r[1].r_a1; break; + case m32c_sim_reg_fb_bank1: val =3D regs.r[1].r_fb; break; + case m32c_sim_reg_sb_bank1: val =3D regs.r[1].r_sb; break; +=20 + case m32c_sim_reg_usp: val =3D regs.r_usp; break; + case m32c_sim_reg_isp: val =3D regs.r_isp; break; + case m32c_sim_reg_pc: val =3D regs.r_pc; break; + case m32c_sim_reg_intb: + val =3D regs.r_intbl * 65536 + regs.r_intbl; break; + case m32c_sim_reg_flg: val =3D regs.r_flags; break; +=20 + /* 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; +=20 + default: + fprintf (stderr, "m32c minisim: unrecognized register number: %d\n", + regno); + return -1; + } +=20 + put_le (buf, length, val); + } +=20 + return size; + } +=20 + int + sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int lengt= h) + { + size_t size; +=20 + check_desc (sd); +=20 + if (! check_regno (regno)) + return 0; +=20 + size =3D reg_size (regno); +=20 + if (length =3D=3D size) + { + DI val =3D get_le (buf, length); +=20 + switch (regno) + { + case m32c_sim_reg_r0_bank0: regs.r[0].r_r0 =3D val & 0xffff; break; + case m32c_sim_reg_r1_bank0: regs.r[0].r_r1 =3D val & 0xffff; break; + case m32c_sim_reg_r2_bank0: regs.r[0].r_r2 =3D val & 0xffff; break; + case m32c_sim_reg_r3_bank0: regs.r[0].r_r3 =3D val & 0xffff; break; + case m32c_sim_reg_a0_bank0: regs.r[0].r_a0 =3D val & addr_mask; break; + case m32c_sim_reg_a1_bank0: regs.r[0].r_a1 =3D val & addr_mask; break; + case m32c_sim_reg_fb_bank0: regs.r[0].r_fb =3D val & addr_mask; break; + case m32c_sim_reg_sb_bank0: regs.r[0].r_sb =3D val & addr_mask; break; + case m32c_sim_reg_r0_bank1: regs.r[1].r_r0 =3D val & 0xffff; break; + case m32c_sim_reg_r1_bank1: regs.r[1].r_r1 =3D val & 0xffff; break; + case m32c_sim_reg_r2_bank1: regs.r[1].r_r2 =3D val & 0xffff; break; + case m32c_sim_reg_r3_bank1: regs.r[1].r_r3 =3D val & 0xffff; break; + case m32c_sim_reg_a0_bank1: regs.r[1].r_a0 =3D val & addr_mask; break; + case m32c_sim_reg_a1_bank1: regs.r[1].r_a1 =3D val & addr_mask; break; + case m32c_sim_reg_fb_bank1: regs.r[1].r_fb =3D val & addr_mask; break; + case m32c_sim_reg_sb_bank1: regs.r[1].r_sb =3D val & addr_mask; break; +=20 + case m32c_sim_reg_usp: regs.r_usp =3D val & addr_mask; break; + case m32c_sim_reg_isp: regs.r_isp =3D val & addr_mask; break; + case m32c_sim_reg_pc: regs.r_pc =3D val & membus_mask; break; + case m32c_sim_reg_intb: + regs.r_intbl =3D (val & membus_mask) & 0xffff; + regs.r_intbh =3D (val & membus_mask) >> 16; + break; + case m32c_sim_reg_flg: regs.r_flags =3D val & 0xffff; break; +=20 + /* 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; +=20 + default: + fprintf (stderr, "m32c minisim: unrecognized register number: %d\n", + regno); + return -1; + } + } +=20 + return size; + } +=20 + void + sim_info (SIM_DESC sd, int verbose) + { + check_desc (sd); +=20 + printf ("The m32c minisim doesn't collect any statistics.\n"); + } +=20 + static volatile int stop; + static enum sim_stop reason; + int siggnal; +=20 +=20 + /* 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 +=20 + case 5: + return SIGTRAP; +=20 + case 10: + #ifdef SIGBUS + return SIGBUS; + #else + return SIGSEGV; + #endif +=20 + case 11:=20 + return SIGSEGV; +=20 + case 24: + #ifdef SIGXCPU + return SIGXCPU; + #else + break; + #endif +=20 + case 2: + return SIGINT; +=20 + case 8: + #ifdef SIGFPE + return SIGFPE; + #else + break; + #endif +=20 + case 6: + return SIGABRT; + } +=20 + return 0; + } +=20 +=20 + /* 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 =3D sim_stopped; + siggnal =3D TARGET_SIGNAL_TRAP; + } + else if (M32C_STOPPED (rc)) + { + reason =3D sim_stopped; + siggnal =3D m32c_signal_to_host (M32C_STOP_SIG (rc)); + } + else + { + assert (M32C_EXITED (rc)); + reason =3D sim_exited; + siggnal =3D M32C_EXIT_STATUS (rc); + } + } +=20 +=20 + void + sim_resume (SIM_DESC sd, int step, int sig_to_deliver) + { + check_desc (sd); +=20 + if (sig_to_deliver !=3D 0) + { + fprintf (stderr,=20 + "Warning: the m32c minisim does not implement " + "signal delivery yet.\n" + "Resuming with no signal.\n"); + } +=20 + 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 =3D 0; + reason =3D sim_stopped; + siggnal =3D TARGET_SIGNAL_INT; + break; + } +=20 + int rc =3D decode_opcode (); +=20 + if (! M32C_STEPPED (rc)) + { + handle_step (rc); + break; + } + } + } + } +=20 + int + sim_stop (SIM_DESC sd) + { + stop =3D 1; +=20 + return 1; + } +=20 + void + sim_stop_reason (SIM_DESC sd, enum sim_stop *reason_p, int *sigrc_p) + { + check_desc (sd); +=20 + *reason_p =3D reason; + *sigrc_p =3D siggnal; + } +=20 + void + sim_do_command (SIM_DESC sd, char *cmd) + { + check_desc (sd); +=20 + char *p =3D cmd; +=20 + /* Skip leading whitespace. */ + while (isspace (*p)) + p++; +=20 + /* Find the extent of the command word. */ + for (p =3D cmd; *p; p++) + if (isspace (*p)) + break; +=20 + /* Null-terminate the command word, and record the start of any + further arguments. */ + char *args; + if (*p) + { + *p =3D '\0'; + args =3D p + 1; + while (isspace (*args)) + args++; + } + else + args =3D p; +=20 + if (strcmp (cmd, "trace") =3D=3D 0) + { + if (strcmp (args, "on") =3D=3D 0) + trace =3D 1; + else if (strcmp (args, "off") =3D=3D 0) + trace =3D 0; + else + printf ("The 'sim trace' command expects 'on' or 'off' " + "as an argument.\n"); + } + else if (strcmp (cmd, "verbose") =3D=3D 0) + { + if (strcmp (args, "on") =3D=3D 0) + verbose =3D 1; + else if (strcmp (args, "off") =3D=3D 0) + verbose =3D 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 +=20 + .global _foo + _foo: + mov.b #2,r0l + ste.b r0l,0xe0000 + rts Index: sim/m32c/int.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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" +=20 + void + trigger_fixed_interrupt (int addr) + { + int s =3D get_reg (sp); + int f =3D get_reg (flags); + int p =3D get_reg (pc); +=20 + if (A16) + { + s -=3D 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 -=3D 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); + } +=20 + void + trigger_based_interrupt (int vector) + { + int addr =3D get_reg (intb) + vector * 4; + if (vector <=3D 31) + set_flags (FLAGBIT_U, 0); + trigger_fixed_interrupt (addr); + } Index: sim/m32c/int.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 + #include + #include +=20 + #include "bfd.h" +=20 + #include "cpu.h" + #include "mem.h" +=20 + int (*decode_opcode)() =3D 0; + int default_machine =3D 0; +=20 + 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 =3D 0; + break; + } + } +=20 + void + m32c_load (bfd *prog) + { + asection *s; + unsigned long mach =3D bfd_get_mach (prog); + unsigned long highest_addr_loaded =3D 0; +=20 + if (mach =3D=3D 0 && default_machine !=3D 0) + mach =3D default_machine; +=20 + m32c_set_mach (mach); +=20 + for (s =3D prog->sections; s; s =3D s->next)=20 + { + #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 =3D bfd_get_section_size (s) + bfd_section_lma (prog, s= ); + if (heaptop < secend && bfd_section_lma (prog, s) < 0x10000) + { + heaptop =3D heapbottom =3D secend; + } + } + } + #endif + if (s->flags & SEC_LOAD) + { + char *buf; + bfd_size_type size; +=20 + size =3D bfd_get_section_size (s); + if (size <=3D 0) + continue; +=20 + bfd_vma base =3D bfd_section_lma (prog, s); + if (verbose) + fprintf(stderr, "[load a=3D%08x s=3D%08x %s]\n", + (int)base, (int)size, bfd_get_section_name (prog, s)); + buf =3D (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 >=3D 4) + highest_addr_loaded =3D base + size - 1; + } + } +=20 + if (strcmp (bfd_get_target (prog), "srec") =3D=3D 0) + { + heaptop =3D heapbottom =3D 0; + switch (mach) + { + case bfd_mach_m16c: + if (highest_addr_loaded > 0x10000) + regs.r_pc =3D mem_get_si (0x000ffffc) & membus_mask; + else + regs.r_pc =3D mem_get_si (0x000fffc) & membus_mask; + break; + case bfd_mach_m32c: + regs.r_pc =3D mem_get_si (0x00fffffc) & membus_mask; + break; + } + } + else + regs.r_pc =3D prog->start_address; + if (verbose) + fprintf(stderr, "[start pc=3D%08x]\n", (unsigned int)regs.r_pc); + } Index: sim/m32c/load.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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" +=20 + extern int default_machine; +=20 + void m32c_set_mach (int mach); + void m32c_load (bfd *); Index: sim/m32c/m32c.opc =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 /* -*- mode: c -*- */ + #include +=20 + #include "cpu.h" + #include "mem.h" + #include "misc.h" + #include "int.h" +=20 + #define AU __attribute__((unused)) +=20 + #define tprintf if (trace) printf +=20 + static unsigned char + getbyte () + { + int tsave =3D trace; + unsigned char b; +=20 + if (trace =3D=3D 1) + trace =3D 0; + b =3D mem_get_pc (); + regs.r_pc ++; + trace =3D tsave; + return b; + } +=20 + #define M32C_ONLY() /* FIXME: add something here */ +=20 + #define GETBYTE() (op[opi++] =3D getbyte()) +=20 + #define UNSUPPORTED() unsupported("unsupported", orig_pc) + #define NOTYET() unsupported("unimplemented", orig_pc) +=20 + static void + unsupported (char *tag, int orig_pc) + { + int i; + printf("%s opcode at %08x\n", tag, orig_pc); + regs.r_pc =3D orig_pc; + for (i=3D0; i<2; i++) + { + int b =3D mem_get_pc(); + printf(" %s", bits(b>>4, 4)); + printf(" %s", bits(b, 4)); + regs.r_pc ++; + } + printf("\n"); + regs.r_pc =3D orig_pc; + for (i=3D0; i<6; i++) + { + printf(" %02x", mem_get_pc ()); + regs.r_pc ++; + } + printf("\n"); + exit(1); + } +=20 + static int + IMM(int bytes) + { + int rv =3D 0; + switch (bytes) + { + case 1: + rv =3D mem_get_qi (get_reg(pc)); + break; + case 2: + rv =3D mem_get_hi (get_reg(pc)); + break; + case 3: + rv =3D mem_get_psi (get_reg(pc)); + break; + case 4: + rv =3D mem_get_si (get_reg(pc)); + break; + } + regs.r_pc +=3D bytes; + return rv; + } +=20 + #define IMM4() (immm >=3D 8 ? 7 - immm : immm + 1) +=20 + #define NO_PREFIX() PREFIX(0,0,0) +=20 + void + prefix (src_allowed, dest_allowed, index_bytewidth) + { + } +=20 + #define MATH_OP(dc,s,c,op) \ + { \ + int ma, mb; \ + ma =3D get_src(dc); \ + mb =3D s & b2mask[dc.bytes]; \ + ll =3D (long long)ma op (long long)mb op c; \ + tprintf("0x%x " #op " 0x%x " #op " 0x%x =3D 0x%llx\n", ma, mb, c, ll); \ + ma =3D sign_ext (ma, dc.bytes * 8); \ + mb =3D sign_ext (s, dc.bytes * 8); \ + v =3D ma op mb op c; \ + tprintf("%d " #op " %d " #op " %d =3D %d\n", ma, mb, c, v); \ + set_oszc (v, dc.bytes, ll > ((1 op 1) ? b2mask[dc.bytes] : 0)); \ + put_dest (dc, v); \ + } +=20 + #define LOGIC_OP(dc,s,op) \ + { \ + int ma, mb; \ + ma =3D get_src(dc); \ + mb =3D s & b2mask[dc.bytes]; \ + v =3D ma op mb; \ + tprintf("0x%x " #op " 0x%x =3D 0x%x\n", ma, mb, v); \ + set_sz (v, dc.bytes); \ + put_dest (dc, v); \ + } +=20 + #define BIT_OP(dc,bit,expr) \ + b =3D get_bit2 (dc, bitindex =3D=3D -1 ? bit : bitindex); \ + v =3D expr; \ + tprintf ("b=3D%d, bit=3D%d, carry=3D%d, %s =3D %d\n", b, bitindex =3D= =3D -1 ? bit : bitindex, carry, #expr, v); \ + put_bit2 (dc, bitindex =3D=3D -1 ? bit : bitindex, v); +=20 + #define BIT_OPC(dc,bit,expr) \ + b =3D get_bit2 (dc, bitindex =3D=3D -1 ? bit : bitindex); \ + v =3D expr; \ + tprintf ("b=3D%d, bit=3D%d, carry=3D%d, %s =3D %d\n", b, bitindex =3D= =3D -1 ? bit : bitindex, carry, #expr, v); \ + set_c (v); +=20 + #define carry (FLAG_C ? 1 : 0) +=20 + static void + cmp (int d, int s, int bytes) + { + int a, b, f=3D0; + a =3D d - s; + b =3D sign_ext (d, bytes*8) - sign_ext (s, bytes*8); + tprintf ("cmp: %x - %x =3D %08x, %x - %x =3D %d\n", + d, s, a, + sign_ext(d,bytes*8), sign_ext(s,bytes*8), b); +=20 + if (b =3D=3D 0) + f |=3D FLAGBIT_Z; + if (b & b2signbit[bytes]) + f |=3D FLAGBIT_S; + if ((d & b2mask[bytes]) >=3D (s & b2mask[bytes])) + f |=3D FLAGBIT_C; + if (b < b2minsigned[bytes] || b > b2maxsigned[bytes]) + f |=3D FLAGBIT_O; +=20 + set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f); + } +=20 + 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=3D0, res; +=20 + prefix (0, 0, 0); +=20 + if (!imm) + { + sc =3D decode_src23 (sss, ss, w+1); + b =3D get_src (sc); + } + dc =3D decode_dest23 (ddd, dd, w+1); + a =3D get_src (dc); + if (imm) + b =3D IMM(w+1); +=20 + a =3D bcd2int(a, w); + b =3D bcd2int(b, w); +=20 + tprintf("decimal: %d %s %d", a, add?"+":"-", b); + if (cy) + tprintf(" c=3D%d", carry); +=20 + if (add) + { + res =3D a + b; + if (cy) + res +=3D carry; + cy =3D res > (w ? 9999 : 99); + } + else + { + res =3D a - b; + if (cy) + res -=3D (1-carry); + cy =3D res >=3D 0; + if (res < 0) + res +=3D w ? 10000 : 100; + } +=20 + res =3D int2bcd (res, w); + tprintf(" =3D %x\n", res); +=20 + set_szc (res, w+1, cy); +=20 + 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) +=20 + static void + div_op (int sss, int ss, int u, int x, int bytes) + { + srcdest sc; + int s, v, a, b; +=20 + if (sss =3D=3D -1) + s =3D IMM(bytes); + else + { + sc =3D decode_dest23 (sss, ss, bytes); + s =3D get_src (sc); + } +=20 + v =3D get_reg (bytes > 1 ? r2r0 : r0); +=20 + if (!u) + { + /* FIXME? do we sign extend a0/a1 to .L? Docs say zero extend. */ + s =3D sign_ext (s, bytes*8); + v =3D sign_ext (v, bytes*8); + } +=20 + if (s =3D=3D 0) + { + set_flags (FLAGBIT_O, FLAGBIT_O); + return; + } +=20 + if (u) + { + a =3D (unsigned int)v / (unsigned int)s; + b =3D (unsigned int)v % (unsigned int)s; + } + else + { + a =3D v / s; + b =3D v % s; + } + if (x) + { + if ((s > 0 && b < 0) + || (s < 0 && b > 0)) + { + a --; + b +=3D s; + } + } + tprintf ("%d / %d =3D %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); +=20 + 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; + } + } +=20 + static void + index_op (int sss, int ss, int do_s, int do_d, int scale, int w) + { + srcdest sc =3D decode_src23 (sss, ss, w+1); + int v =3D get_src (sc) * scale; + tprintf("%d =3D %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 +=20 + static void + rot_op (srcdest sd, int rotc, int count) + { + int mask =3D (sd.bytes =3D=3D 2) ? 0xffff : 0xff; + int msb =3D (sd.bytes =3D=3D 2) ? 0x8000 : 0x80; + int v =3D get_src (sd); + int c =3D carry, ct; +=20 + 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 =3D (v & msb) ? 1 : 0; + v <<=3D 1; + v |=3D rotc ? c : ct; + v &=3D mask; + c =3D ct; + tprintf (": %s %d\n", bits(v, 8*sd.bytes), c); + count --; + } + while (count < 0) + { + ct =3D v & 1; + v >>=3D 1; + v |=3D (rotc ? c : ct) * msb; + c =3D ct; + tprintf (": %s %d\n", bits(v, 8*sd.bytes), c); + count ++; + } + put_dest (sd, v); + set_szc (v, sd.bytes, c); + } +=20 + static void + shift_op (srcdest sd, int arith, int count, int setc) + { + int mask =3D (sd.bytes =3D=3D 2) ? 0xffff : 0xff; + int msb =3D (sd.bytes =3D=3D 2) ? 0x8000 : 0x80; + int v =3D get_src (sd); + int c =3D 0; + int o =3D 0; +=20 + if (sd.bytes =3D=3D 4) + { + mask =3D 0xffffffffU; + msb =3D 0x80000000U; + } +=20 + 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 =3D (v & msb) ? 1 : 0; + v <<=3D 1; + v &=3D mask; + if (c !=3D ((v & msb) ? 1 : 0)) + o =3D 1; + tprintf (": %s %d %d\n", bits(v, 8*sd.bytes), c, o); + count --; + } + while (count < 0) + { + c =3D v & 1; + if (arith) + v =3D (v & msb) | (v >> 1); + else + v =3D (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); + } +=20 + 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 =3D -1; + int t0, t1=3D0, t2, t3=3D0; + int ta0, ta1, dif; +=20 + step_result =3D M32C_MAKE_STEPPED (); +=20 + decode_indirect (0, 0); + decode_index (0, 0); +=20 + next_opcode: + opi =3D 0; + orig_pc =3D get_reg (pc); +=20 + tprintf("trace: decode pc =3D %06x\n", orig_pc); +=20 + /* VARY sss 000 001 010 011 100 */ + /* VARY ddd 000 001 010 011 100 */ +=20 + /* 0000 1001 indirect dest */ +=20 + decode_indirect (0, 1); + goto next_opcode; +=20 + /* 0100 0001 indirect src */ +=20 + decode_indirect (1, 0); + goto next_opcode; +=20 + /* 0100 1001 indirect src and dest */ +=20 + decode_indirect (1, 1); + goto next_opcode; +=20 + /* 1010 ddd w dd01 1111 ABS.size dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + v =3D sign_ext (get_src (dc), w?16:8); + a =3D v<0 ? -v : v; + tprintf("abs(%d) =3D %d\n", v, a); + set_osz(a, w+1); + put_dest (dc, a); +=20 + /* 0000 0001 1000 ddd w dd10 1110 ADC.size #IMM,dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + imm =3D IMM (w+1); + MATH_OP (dc, imm, carry, +); +=20 + /* 0000 0001 1sss ddd w dd ss 0100 ADC.size src,dest */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, w+1); + dc =3D decode_dest23 (ddd, dd, w+1); + b =3D get_src (sc); + MATH_OP (dc, b, carry, +); +=20 + /* 1011 ddd w dd01 1110 ADCF.size dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + MATH_OP (dc, 0, carry, +); +=20 + /* 1000 ddd w dd10 1110 ADD.size:G #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23(ddd, dd, w+1); + imm =3D IMM(w+1); + MATH_OP (dc, imm, 0, +); +=20 + /* 1000 ddd0 dd11 0001 ADD.L:G #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23(ddd, dd, 4); + imm =3D IMM(4); + MATH_OP (dc, imm, 0, +); +=20 + /* 111L ddd w dd11 immm ADD.size:Q #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23(ddd, dd, L ? 4 : (w+1)); + imm =3D sign_ext (immm, 4); + MATH_OP (dc, imm, 0, +); +=20 + /* 00dd 011w ADD.size:S #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest2(dd, w+1); + imm =3D IMM (w+1); + MATH_OP (dc, imm, 0, +); +=20 + /* 10i0 110d ADD.L:S #IMM,A0/A1 */ +=20 + prefix (0, 0, 0); + dc =3D reg_sd (d ? a1 : a0); + imm =3D i ? 2 : 1; + MATH_OP (dc, imm, 0, +); +=20 + /* 1sss ddd w dd ss 1000 ADD.size:G src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23(sss, ss, w+1); + dc =3D decode_dest23(ddd, dd, w+1); + b =3D get_src (sc); + MATH_OP (dc, b, 0, +); +=20 + /* 1sss ddd1 dd ss 0010 ADD.L:G src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23(sss, ss, 4); + dc =3D decode_dest23(ddd, dd, 4); + b =3D get_src (sc); + MATH_OP (dc, b, 0, +); +=20 + /* 1011 0110 0001 0011 ADD.L:G #IMM16,SP */ +=20 + prefix (0, 0, 0); + dc =3D reg_sd (sp); + b =3D sign_ext (IMM(2), 16); + MATH_OP (dc, b, 0, +); +=20 + /* 01ii 001i ADD.L:Q #IMM3,SP */ +=20 + prefix (0, 0, 0); + dc =3D reg_sd (sp); + b =3D ii * 2 + i + 1; + MATH_OP (dc, b, 0, +); +=20 + /* 1011 0110 0000 0011 ADD.L:S #IMM8,SP */ +=20 + prefix (0, 0, 0); + dc =3D reg_sd (sp); + b =3D sign_ext (IMM(1), 8); + MATH_OP (dc, b, 0, +); +=20 + /* 1000 ddd0 dd01 0001 ADDX #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23(ddd, dd, 4); + imm =3D sign_ext (IMM(1), 8); + MATH_OP (dc, imm, 0, +); +=20 + /* 1sss ddd0 dd ss 0010 ADDX src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23(sss, ss, 1); + dc =3D decode_dest23(ddd, dd, 4); + b =3D sign_ext (get_src (sc), 8); + MATH_OP (dc, b, 0, +); +=20 + /* 1111 ddd w dd01 immm ADJNZ.size #IMM,dest,label */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + v =3D get_src (dc); + imm =3D sign_ext(immm, 4); + tprintf("%d + %d =3D %d\n", v, imm, v+imm); + v +=3D imm; + put_dest (dc, v); + a =3D sign_ext (IMM(1), 8); + if ((v & (w ? 0xffff : 0xff)) !=3D 0) + { + tprintf("jmp: %x + 2 + %d =3D ", get_reg (pc), a); + put_reg (pc, orig_pc + 2 + a); + tprintf("%x\n", get_reg (pc)); + } +=20 + /* 1000 ddd w dd11 1111 AND.size:G #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23(ddd, dd, w+1); + imm =3D IMM(w+1); + LOGIC_OP (dc, imm, &); +=20 + /* 01dd 110w AND.size:S #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest2(dd, w+1); + imm =3D IMM (w+1); + LOGIC_OP (dc, imm, &); +=20 + /* 1sss ddd w dd ss 1101 AND.size:G src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23(sss, ss, w+1); + dc =3D decode_dest23(ddd, dd, w+1); + b =3D get_src (sc); + LOGIC_OP (dc, b, &); +=20 + /* 0000 0001 1101 sss0 ss00 1bit BAND src */ +=20 + sc =3D decode_src23 (sss, ss, 1); + BIT_OPC (sc, bit, b & carry); +=20 + /* 1101 ddd0 dd11 0bit BCLR dest */ +=20 + dc =3D decode_dest23 (ddd, dd, 1); + BIT_OP (dc, bit, 0); +=20 + /* 1100 ddd w dd10 1110 BITINDEX.size src */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + bitindex =3D get_src (dc); + tprintf ("bitindex set to %d\n", bitindex); + goto next_opcode; +=20 + /* 1101 ddd0 dd01 0bit BMcnd dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, 1); + if (condition_true (IMM (1))) + put_bit2 (dc, bit, 1); + else + put_bit2 (dc, bit, 0); +=20 + /* 1101 1001 0c10 1cnd BMcnd C */ +=20 + prefix (0, 0, 0); + if (condition_true (c * 8 + cnd)) + set_c (1); + else + set_c (0); +=20 + /* 0000 0001 1101 sss0 ss01 1bit BNAND src */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 1); + BIT_OPC (sc, bit, !b & carry); +=20 + /* 0000 0001 1101 sss0 ss11 0bit BNOR src */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 1); + BIT_OPC (sc, bit, !b | carry); +=20 + /* 1101 ddd0 dd01 1bit BNOT dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, 1); + BIT_OP (dc, bit, !b); +=20 + /* 0000 0001 1101 sss0 ss00 0bit BNTST src */ +=20 + prefix (0, 0, 0); + sc =3D decode_dest23 (sss, ss, 1); + b =3D get_bit2 (sc, bit); + set_zc (!b, !b); +=20 + /* 0000 0001 1101 sss0 ss11 1bit BNXOR src */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 1); + BIT_OPC (sc, bit, !b ^ carry); +=20 + /* 0000 0001 1101 sss0 ss10 0bit BOR src */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 1); + BIT_OPC (sc, bit, b | carry); +=20 + /* 0000 0000 BRK */ +=20 + /* We report the break to our caller with the PC still pointing at the= =20 + breakpoint instruction. */ + put_reg (pc, orig_pc); + if (verbose) + printf("[break]\n"); + return M32C_MAKE_HIT_BREAK (); +=20 + /* 0000 1000 BRK */ +=20 + if (verbose) + printf("[break2]\n"); + return M32C_MAKE_HIT_BREAK (); +=20 + /* 1101 ddd0 dd11 1bit BSET dest */ +=20 + dc =3D decode_dest23 (ddd, dd, 1); + BIT_OP (dc, bit, 1); +=20 + /* 1101 sss0 ss00 0bit BTST:G src */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 1); + b =3D get_bit2 (sc, bit); + set_zc (!b, b); +=20 + /* 00bb 101b BTST:S src */ +=20 + sc =3D decode_src23 (3, 3, 1); /* bit,base:19 */ + b =3D get_bit2 (sc, bb*2 + b); + set_zc (!b, b); +=20 + /* 1101 ddd0 dd10 0bit BTSTC dest */ +=20 + prefix (0, 0, 0); + sc =3D decode_dest23 (ddd, dd, 1); + b =3D get_bit2 (sc, bit); + set_zc (!b, b); + put_bit2 (sc, bit, 0); +=20 + /* 1101 ddd0 dd10 1bit BTSTS dest */ +=20 + prefix (0, 0, 0); + sc =3D decode_dest23 (ddd, dd, 1); + b =3D get_bit2 (sc, bit); + set_zc (!b, b); + put_bit2 (sc, bit, 1); +=20 + /* 0000 0001 1101 sss0 ss10 1bit BXOR src */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 1); + BIT_OPC (sc, bit, b ^ carry); +=20 + /* 0000 0001 1000 ddd w dd11 1110 CLIP.size #IMM1,#IMM2,dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + a =3D sign_ext (IMM(w+1), w*8+8); + b =3D sign_ext (IMM(w+1), w*8+8); + v =3D sign_ext (get_src (dc), w*8+8); + tprintf("clip %d <=3D %d <=3D %d : ", a, v, b); + if (a > v) + v =3D a; + if (v > b) + v =3D b; + tprintf("%d\n", v); + put_dest (dc, v); +=20 + /* 1001 ddd w dd10 1110 CMP.size:G #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + v =3D get_src (dc); + imm =3D IMM(w+1); + cmp (v, imm, w+1); +=20 + /* 1010 ddd0 dd11 0001 CMP.L:G #IMM32,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, 4); + v =3D get_src (dc); + imm =3D IMM(4); + cmp (v, imm, 4); +=20 + /* 1110 ddd w dd01 immm CMP.size:Q #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + v =3D get_src (dc); + immm =3D sign_ext (immm, 4); + cmp (v, immm, w+1); +=20 + /* 01dd 011w CMP.size:S #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest2 (dd, w+1); + v =3D get_src (dc); + imm =3D sign_ext (IMM(w+1),w*8+8); + cmp (v, imm, w+1); +=20 + /* 1sss ddd w dd ss 0110 CMP.size:G src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23 (sss, ss, w+1); + dc =3D decode_dest23 (ddd, dd, w+1); + a =3D get_src (dc); + b =3D get_src (sc); + cmp (a, b, w+1); +=20 + /* 1sss ddd1 dd ss 0001 CMP.L:G src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23 (sss, ss, 4); + dc =3D decode_dest23 (ddd, dd, 4); + a =3D get_src (dc); + b =3D get_src (sc); + cmp (a, b, 4); +=20 + /* 01dd 000w CMP.size:S src,R0/R0L */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest2 (dd, w+1); + a =3D get_reg (w ? r0 : r0l); + b =3D get_src (dc); + cmp (a, b, w+1); +=20 + /* 1010 ddd0 dd01 0001 CMPX #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, 4); + v =3D get_src (dc); + imm =3D sign_ext (IMM(1), 8); + cmp (v, imm, 4); +=20 + /* 0000 0001 1000 ddd w dd00 1110 DADC.size #IMM,dest */ +=20 + DADDI(1,1); +=20 + /* 0000 0001 1sss ddd w dd ss 1000 DADC.size src,dest */ +=20 + DADDV(1,1); +=20 + /* 0000 0001 1000 ddd w dd01 1110 DADD.size #IMM,dest */ +=20 + DADDI(1,0); +=20 + /* 0000 0001 1sss ddd w dd ss 0000 DADD.size src,dest */ +=20 + DADDV(1,0); +=20 + /* 1011 ddd w dd00 1110 DEC.size dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + a =3D get_src (dc); + v =3D a-1; + tprintf ("%x -- =3D %x\n", a, v); + set_sz (v, w+1); + put_dest (dc, v); +=20 + /* 1011 0000 010w 0011 DIV.size #IMM */ +=20 + prefix (0, 0, 0); + div_op (-1, 0, 0, 0, w+1); +=20 + /* 1000 sss w ss01 1110 DIV.size src */ +=20 + prefix (0, 1, 0); + div_op (sss, ss, 0, 0, w+1); +=20 + /* 0000 0001 1010 sss1 ss01 1111 DIV.L src */ +=20 + M32C_ONLY(); + prefix (0, 0, 0); + div_op (sss, ss, 0, 0, 4); +=20 + /* 1011 0000 000w 0011 DIVU.size #IMM */ +=20 + prefix (0, 0, 0); + div_op (-1, 0, 1, 0, w+1); +=20 + /* 1000 sss w ss00 1110 DIVU.size src */ +=20 + prefix (0, 1, 0); + div_op (sss, ss, 1, 0, w+1); +=20 + /* 0000 0001 1010 sss1 ss00 1111 DIVU.L src */ +=20 + M32C_ONLY(); + prefix (0, 0, 0); + div_op (sss, ss, 1, 0, 4); +=20 + /* 1011 0010 010w 0011 DIVX.size #IMM */ +=20 + prefix (0, 0, 0); + div_op (-1, 0, 0, 1, w+1); +=20 + /* 1001 sss w ss01 1110 DIVX.size src */ +=20 + prefix (0, 1, 0); + div_op (sss, ss, 0, 1, w+1); +=20 + /* 0000 0001 1010 sss1 ss10 1111 DIVX.L src */ +=20 + M32C_ONLY(); + prefix (0, 0, 0); + div_op (sss, ss, 0, 1, 4); +=20 + /* 0000 0001 1001 ddd w dd00 1110 DSBB.size #IMM,dest */ +=20 + DADDI(0,1); +=20 + /* 0000 0001 1sss ddd w dd ss 1010 DSBB.size src,dest */ +=20 + DADDV(0,1); +=20 + /* 0000 0001 1001 ddd w dd01 1110 DSUB.size #IMM,dest */ +=20 + DADDI(0,0); +=20 + /* 0000 0001 1sss ddd w dd ss 0010 DSUB.size src,dest */ +=20 + DADDV(0,0); +=20 + /* 1110 1100 ENTER #IMM */ +=20 + imm =3D 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); +=20 + /* 1111 1100 EXITD */ +=20 + 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); +=20 + /* 1100 ddd w dd01 1110 EXTS.size dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + v =3D sign_ext (get_src (dc), (w+1)*8); + dc =3D widen_sd (dc); + put_dest (dc, v); + set_sz (v, (w+1)*2); +=20 + /* 0000 0001 1sss ddd0 dd ss 0111 EXTS.B src,dest */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 1); + dc =3D decode_dest23 (ddd, dd, 2); + v =3D sign_ext (get_src (sc), 8); + put_dest (dc, v); + set_sz (v, 16); +=20 + /* 0000 0001 1sss ddd0 dd ss 1011 EXTZ src,dest */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 1); + dc =3D decode_dest23 (ddd, dd, 2); + v =3D get_src (sc); + put_dest (dc, v); + set_sz (v, 16); +=20 + /* 1101 0011 1110 1dst FCLR dest */ +=20 + set_flags (1 << dst, 0); +=20 + /* 1001 1111 FREIT */ +=20 + NOTYET(); +=20 + /* 1101 0001 1110 1dst FSET dest */ +=20=20=20 + set_flags (1 << dst, 1 << dst); +=20 + /* 1010 ddd w dd00 1110 INC.size dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + a =3D get_src (dc); + v =3D a+1; + tprintf ("%x ++ =3D %x\n", a, v); + set_sz (v, w+1); + put_dest (dc, v); +=20 + /* 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); +=20 + /* 1011 1110 vector00 INT #IMM */ +=20 + prefix (0, 0, 0); + trigger_based_interrupt (vector); +=20 + /* 1011 1111 INTO */ +=20 + prefix (0, 0, 0); + if (FLAG_O) + trigger_fixed_interrupt (0xffffe0); +=20 + /* 1ccc 101c Jcnd label */ +=20 + prefix (0, 0, 0); + v =3D sign_ext (IMM(1), 8); + if (condition_true (ccc*2+c)) + put_reg (pc, orig_pc + 1 + v); +=20 + /* 01dd 101d JMP.S label */ +=20 + prefix (0, 0, 0); + put_reg (pc, orig_pc + (dd*2+d) + 2); +=20 + /* 1011 1011 JMP.B label */ +=20 + prefix (0, 0, 0); + imm =3D sign_ext (IMM(1), 8); + if (imm =3D=3D -1) + { + if (verbose) + printf("[jmp-to-self detected as exit]\n"); + return M32C_MAKE_HIT_BREAK (); + } + put_reg (pc, orig_pc + 1 + imm); +=20 + /* 1100 1110 JMP.W label */ +=20 + prefix (0, 0, 0); + imm =3D sign_ext (IMM(2), 16); + put_reg (pc, orig_pc + 1 + imm); +=20 + /* 1100 1100 JMP.A label */ +=20=20=20 + prefix (0, 0, 0); + imm =3D IMM(3); + put_reg (pc, imm); +=20 + /* 1100 sss1 ss00 1111 JMPI.W src */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 2); + a =3D get_src (sc); + a =3D sign_ext (a, 16); + put_reg (pc, orig_pc + a); +=20 + /* 1000 sss0 ss00 0001 JMPI.A src */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 3); + a =3D get_src (sc); + put_reg (pc, a); +=20 + /* 1101 1100 JMPS #IMM8 */ +=20 + prefix (0, 0, 0); + imm =3D IMM(1); + a =3D 0xff0000 + mem_get_hi (0xfffe00 - imm * 2); + put_reg (pc, a); +=20 + /* 1100 1111 JSR.W label */ +=20 + prefix (0, 0, 0); + imm =3D 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); +=20 + /* 1100 1101 JSR.A label */ +=20 + prefix (0, 0, 0); + imm =3D IMM(3); + put_reg (sp, get_reg (sp) - 4); + mem_put_si (get_reg (sp), get_reg (pc)); + put_reg (pc, imm); +=20 + /* 1100 sss1 ss01 1111 JSRI.W src */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 2); + a =3D get_src (sc); + a =3D 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); +=20 + /* 1001 sss0 ss00 0001 JSRI.A src */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 3); + a =3D get_src (sc); + put_reg (sp, get_reg (sp) - 4); + mem_put_si (get_reg (sp), get_reg (pc)); + put_reg (pc, a); +=20 + /* 1101 1101 JSRS #IMM8 */ +=20 + prefix (0, 0, 0); + imm =3D IMM(1); + a =3D 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); +=20 + /* 1101 0101 1010 1dst LDC #IMM16,dest */ +=20 + imm =3D IMM(2); + dc =3D decode_cr_b (dst, CR_B_DCT0); + put_dest (dc, imm); +=20 + /* 1101 0101 0010 1dst LDC #IMM24,dest */ +=20 + imm =3D IMM(3); + dc =3D decode_cr_b (dst, CR_B_INTB); + put_dest (dc, imm); +=20 + /* 1101 0101 0110 1dst LDC #IMM24,dest */ +=20 + imm =3D IMM(3); + dc =3D decode_cr_b (dst, CR_B_DMA0); + put_dest (dc, imm); +=20 + /* 0000 0001 1101 sss1 ss00 1dst LDC src,dest */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 2); + dc =3D decode_cr_b (dst, CR_B_DCT0); + a =3D get_src (sc); + put_dest (dc, a); +=20 + /* 1101 sss1 ss00 0dst LDC src,dest */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 3); + dc =3D decode_cr_b (dst, CR_B_INTB); + a =3D get_src (sc); + put_dest (dc, a); +=20 + /* 0000 0001 1101 sss1 ss00 0dst LDC src,dest */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 3); + dc =3D decode_cr_b (dst, CR_B_DMA0); + a =3D get_src (sc); + put_dest (dc, a); +=20 + /* 1011 0110 1100 0011 LDCTX */ +=20 + NOTYET(); +=20 + /* 1101 0101 1110 1imm LDIPL #IMM */ +=20 + set_flags (0x7000, imm*0x1000); +=20 + /* 0000 0001 1000 ddd w dd11 1111 MAX.size #IMM,dest */ +=20 + prefix (0, 0, 0); + w++; + dc =3D decode_dest23 (ddd, dd, w); + imm =3D sign_ext (IMM(w), w*8); + a =3D sign_ext (get_src (dc), w*8); + tprintf ("max %d %d\n", imm, a); + if (imm > a) + put_dest (dc, imm); +=20 + /* 0000 0001 1sss ddd w dd ss 1101 MAX.size src,dest */ +=20 + prefix (0, 0, 0); + w++; + sc =3D decode_src23 (sss, ss, w); + dc =3D decode_dest23 (ddd, dd, w); + b =3D sign_ext (get_src (sc), w*8); + a =3D sign_ext (get_src (dc), w*8); + tprintf ("max %d %d\n", b, a); + if (b > a) + put_dest (dc, b); +=20 + /* 0000 0001 1000 ddd w dd10 1111 MIN.size #IMM,dest */ +=20 + prefix (0, 0, 0); + w++; + dc =3D decode_dest23 (ddd, dd, w); + imm =3D sign_ext (IMM(w), w*8); + a =3D sign_ext (get_src (dc), w*8); + tprintf ("min %d %d\n", imm, a); + if (imm < a) + put_dest (dc, imm); +=20 + /* 0000 0001 1sss ddd w dd ss 1100 MIN.size src,dest */ +=20 + prefix (0, 0, 0); + w++; + sc =3D decode_src23 (sss, ss, w); + dc =3D decode_dest23 (ddd, dd, w); + b =3D sign_ext (get_src (sc), w*8); + a =3D sign_ext (get_src (dc), w*8); + tprintf ("min %d %d\n", b, a); + if (b < a) + put_dest (dc, b); +=20 + /* 1001 ddd w dd10 1111 MOV.size:G #IMM,dest */ +=20 + dc =3D decode_dest23 (ddd, dd, w+1); + imm =3D IMM(w+1); + v =3D imm; + tprintf("%x =3D %x\n", v, v); + set_sz(v, w+1); + put_dest (dc, v); +=20 + /* 1011 ddd0 dd11 0001 MOV.L:G #IMM,dest */ +=20 + dc =3D decode_dest23 (ddd, dd, 4); + imm =3D IMM(4); + v =3D imm; + tprintf("%x =3D %x\n", v, v); + set_sz(v, 4); + put_dest (dc, v); +=20 + /* 1111 ddd w dd10 immm MOV.size:Q #IMM4,dest */ +=20 + dc =3D decode_dest23 (ddd, dd, w+1); + imm =3D sign_ext (immm, 4); + v =3D imm; + tprintf("%x =3D %d\n", v, v); + set_sz(v, w+1); + put_dest (dc, v); +=20 + /* 00dd 010w MOV.size:S #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest2 (dd, w+1); + imm =3D IMM(w+1); + put_dest (dc, imm); + set_sz (imm, w+1); +=20 + /* 10w1 110d MOV.size:S #IMM,a0/a1 */ +=20 + imm =3D IMM(w ? 3 : 2); + put_reg (d ? a1 : a0, imm); + set_sz (imm & addr_mask, w+1); +=20 + /* 00dd 001w MOV.size:Z #0,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest2 (dd, w+1); + put_dest (dc, 0); + set_sz (0, w+1); +=20 + /* 1sss ddd w dd ss 1011 MOV.size:G src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23 (sss, ss, w+1); + dc =3D decode_dest23 (ddd, dd, w+1); + v =3D get_src (sc); + put_dest (dc, v); + set_sz (v, w+1); +=20 + /* 1sss ddd1 dd ss 0011 MOV.L:G src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23 (sss, ss, 4); + dc =3D decode_dest23 (ddd, dd, 4); + v =3D get_src (sc); + put_dest (dc, v); + set_sz (v, 4); +=20 + /* VARY SS 01 10 11 */ + /* 00SS 100w MOV.size:S src,R0L/R0 */ +=20 + prefix (0, 1, 0); + sc =3D decode_dest2 (SS, w+1); + v =3D get_src (sc); + put_reg (w ? r0 : r0l, v); + set_sz (v, w+1); +=20 + /* 01ss 111w MOV.size:S src,R1L/R1 */ +=20 + prefix (0, 1, 0); + sc =3D decode_dest2 (ss, w+1); + v =3D get_src (sc); + put_reg (w ? r1 : r1l, v); + set_sz (v, w+1); +=20 + /* VARY DD 01 10 11 */ + /* 00DD 000w MOV.size:S R0L/R0,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest2 (DD, w+1); + v =3D get_reg (w ? r0 : r0l); + put_dest (dc, v); + set_sz (v, w+1); +=20 + /* 01ss 100d MOV.L:S src,A0/A1 */ +=20 + prefix (0, 1, 0); + sc =3D decode_dest2 (ss, 4); + v =3D get_src (sc); + put_reg (d ? a1 : a0, v); + set_sz (v, 4); +=20 + /* 1011 ddd w dd00 1111 MOV.size:G dsp:8[SP], dest */ +=20 + prefix (0, 0, 0); + imm =3D IMM(1); + dc =3D decode_dest23 (ddd, dd, w+1); + a =3D get_reg (sp) + sign_ext (imm, 8); + a &=3D addr_mask; + if (w) + v =3D mem_get_hi (a); + else + v =3D mem_get_qi (a); + put_dest (dc, v); + set_sz (v, w+1); +=20 + /* 1010 sss w ss00 1111 MOV.size:G src,dsp:8[SP] */ +=20 + prefix (0, 0, 0); + sc =3D decode_dest23 (sss, ss, w+1); + imm =3D IMM(1); + a =3D get_reg (sp) + sign_ext (imm, 8); + a &=3D addr_mask; + v =3D get_src (sc); + if (w) + mem_put_hi (a, v); + else + mem_put_qi (a, v); + set_sz (v, w+1); +=20 + /* 1101 sss1 ss01 1dst MOVA src,dest */ +=20 + static reg_id map[8] =3D { r2r0, r3r1, a0, a1 }; + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 1); + if (!sc.mem || !map[dst]) + UNSUPPORTED(); + put_reg (map[dst], sc.u.addr); +=20 + /* 0000 0001 1011 ddd0 dd hl 1110 MOVdir R0L,dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, 1); + a =3D get_src (dc); + b =3D get_reg (r0l); + switch (hl) + { + case 0: a =3D (a & 0xf0) | (b & 0x0f); break; + case 1: a =3D (a & 0xf0) | ((b>>4) & 0x0f); break; + case 2: a =3D (a & 0x0f) | ((b & 0x0f)<<4); break; + case 3: a =3D (a & 0x0f) | (b & 0xf0); break; + } + put_dest (dc, a); +=20 + /* 0000 0001 1010 sss0 ss hl 1110 MOVdir src,R0L */ +=20 + prefix (0, 0, 0); + sc =3D decode_dest23 (sss, ss, 1); + a =3D get_reg (r0l); + b =3D get_src (dc); + switch (hl) + { + case 0: a =3D (a & 0xf0) | (b & 0x0f); break; + case 1: a =3D (a & 0xf0) | ((b>>4) & 0x0f); break; + case 2: a =3D (a & 0x0f) | ((b & 0x0f)<<4); break; + case 3: a =3D (a & 0x0f) | (b & 0xf0); break; + } + put_reg (r0l, a); +=20 + /* 1011 ddd0 dd01 0001 MOVX #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, 4); + imm =3D sign_ext (IMM(1), 8); + put_dest (dc, imm); + set_sz (imm, 1); +=20 + /* 1000 ddd w dd01 1111 MUL.size #IMM,dest */ +=20 + prefix (0, 1, 0); + w ++; + dc =3D decode_dest23 (ddd, dd, w); + v =3D sign_ext (get_src (dc), w*8); + imm =3D sign_ext (IMM(w), w*8); + tprintf("%d * %d =3D %d\n", v, imm, v*imm); + v *=3D imm; + dc =3D widen_sd (dc); + put_dest (dc, v); +=20 + /* 1sss ddd w dd ss 1100 MUL.size src,dest */ +=20 + prefix (1, 1, 0); + w ++; + sc =3D decode_src23 (sss, ss, w); + dc =3D decode_dest23 (ddd, dd, w); + a =3D sign_ext (get_src (sc), w*8); + b =3D sign_ext (get_src (dc), w*8); + tprintf("%d * %d =3D %d\n", a, b, a*b); + v =3D a * b; + dc =3D widen_sd (dc); + put_dest (dc, v); +=20 + /* 0000 0001 1000 sss1 ss01 1111 MUL.L src,R2R0 */ +=20 + M32C_ONLY(); + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 4); + a =3D sign_ext (get_src (sc), 32); + b =3D sign_ext (get_reg (r2r0), 32); + ll =3D (long long)a * (long long)b; + tprintf("%d * %d =3D %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); +=20 + /* 1100 sss1 ss11 1110 MULEX src */ +=20 + prefix (0, 1, 0); + sc =3D decode_dest23 (sss, ss, 2); + a =3D sign_ext (get_src (sc), 16); + b =3D sign_ext (get_reg (r2r0), 32); + ll =3D (long long)a * (long long)b; + tprintf("%d * %d =3D %lld (%llx)\n", a, b, ll, ll); + put_reg (r2r0, (int)ll); + put_reg (r1, (int)(ll >> 32)); +=20 + /* 1000 ddd w dd00 1111 MULU.size #IMM,dest */ +=20 + prefix (0, 1, 0); + w ++; + dc =3D decode_dest23 (ddd, dd, w); + v =3D get_src (dc); + imm =3D IMM(w); + tprintf("%d * %d =3D %d\n", v, imm, v*imm); + v *=3D imm; + dc =3D widen_sd (dc); + put_dest (dc, v); +=20 + /* 1sss ddd w dd ss 0100 MULU.size src,dest */ +=20 + prefix (1, 1, 0); + w ++; + sc =3D decode_src23 (sss, ss, w); + dc =3D decode_dest23 (ddd, dd, w); + a =3D get_src (sc); + b =3D get_src (dc); + tprintf("%d * %d =3D %d\n", a, b, a*b); + v =3D a * b; + dc =3D widen_sd (dc); + put_dest (dc, v); +=20 + /* 0000 0001 1000 sss1 ss00 1111 MULU.L src,R2R0 */ +=20 + M32C_ONLY(); + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, 4); + a =3D get_src (sc); + b =3D get_reg (r2r0); + ll =3D (long long)a * (long long)b; + tprintf("%d * %d =3D %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); +=20 + /* 1010 ddd w dd10 1111 NEG.size dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + a =3D sign_ext (get_src (dc), (w+1)*8); + v =3D -a; + tprintf("%d * -1 =3D %d\n", a, v); + set_oszc(v, w+1, v=3D=3D0); + put_dest (dc, v); +=20 + /* 1101 1110 NOP */ +=20 + tprintf("nop\n"); +=20 + /* 1010 ddd w dd01 1110 NOT.size dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + a =3D get_src (dc); + v =3D ~a; + tprintf("~ %x =3D %x\n", a, v); + set_sz(v, w+1); + put_dest (dc, v); +=20 + /* 1000 ddd w dd10 1111 OR.size:G #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23(ddd, dd, w+1); + imm =3D IMM(w+1); + LOGIC_OP (dc, imm, |); +=20 + /* 01dd 010w OR.size:S #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest2(dd, w+1); + imm =3D IMM (w+1); + LOGIC_OP (dc, imm, |); +=20 + /* 1sss ddd w dd ss 0101 OR.size:G src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23(sss, ss, w+1); + dc =3D decode_dest23(ddd, dd, w+1); + b =3D get_src (sc); + LOGIC_OP (dc, b, |); +=20 + /* 1011 ddd w dd10 1111 POP.size dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + if (w) + a =3D mem_get_hi (get_reg (sp)); + else + a =3D 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); +=20 + /* 1101 0011 1010 1dst POPC dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_cr_b (dst, CR_B_DCT0); + a =3D mem_get_hi (get_reg (sp)); + put_reg (sp, get_reg (sp) + 2); + tprintf("pophi: %x\n", a); + put_dest (dc, a); +=20 + /* 1101 0011 0010 1dst POPC dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_cr_b (dst, CR_B_INTB); + a =3D mem_get_si (get_reg (sp)); + put_reg (sp, get_reg (sp) + 4); + tprintf("popsi: %x\n", a); + put_dest (dc, a); +=20 + /* 1000 1110 POPM dest */ +=20 + static int map[] =3D { r0, r1, r2, r3, a0, a1, sb, fb }; + prefix (0, 0, 0); + imm =3D IMM(1); + tprintf("popm: %x\n", imm); + for (a=3D0; a<4; a++) + if (imm & (1<> 32)); +=20 + /* 1011 ddd w dd10 1110 ROLC.size dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + rot_op (dc, 1, 1); +=20 + /* 1010 ddd w dd10 1110 RORC.size dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + rot_op (dc, 1, -1); +=20 + /* 1110 ddd w dd10 immm ROT.size #IMM, dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + rot_op (dc, IMM4(), -1); +=20 + /* 1010 ddd w dd11 1111 ROT.size R1H,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + a =3D sign_ext (get_reg (r1h), 8); + rot_op (dc, a, -1); +=20 + /* 1101 1111 RTS */ +=20 + put_reg (pc, mem_get_si (get_reg (sp))); + put_reg (sp, get_reg (sp) + 4); +=20 + /* 0000 0001 1001 ddd w dd10 1110 SBB.size #IMM, dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + imm =3D IMM (w+1); + MATH_OP (dc, imm, !carry, -); +=20 + /* 0000 0001 1sss ddd w dd ss 0110 SBB.size src,dest */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, w+1); + dc =3D decode_dest23 (ddd, dd, w+1); + MATH_OP (dc, get_src (sc), !carry, -); +=20 + /* 1101 ddd1 dd11 cond SCcond dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, 2); + if (condition_true (cond)) + put_dest (dc, 1); + else + put_dest (dc, 0); +=20 + /* 1011 1000 110w 0011 SCMPU.size */ +=20 + ta0 =3D get_reg (a0); + ta1 =3D get_reg (a1); +=20 + for (;;) + { + t0 =3D mem_get_qi (ta0); + t2 =3D mem_get_qi (ta1); + if (w) + { + t1 =3D mem_get_qi (ta0 + 1); + t3 =3D mem_get_qi (ta1 + 1); + } + dif =3D t0 - t2; + if (dif =3D=3D 0 && t0 !=3D 0 && w) + dif =3D t1 - t3; + set_oszc (dif, 1, dif > 0); +=20 + ta0 +=3D w ? 2 : 1; + ta1 +=3D w ? 2 : 1; +=20 + if (t0 =3D=3D 0 || t0 !=3D t2) + break; + if (w && (t1 =3D=3D 0 || t1 !=3D t3)) + break; + } +=20 + /* 1111 ddd w dd00 immm SHA.size #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + shift_op (dc, 1, IMM4(), 1); +=20 + /* 1010 ddd0 dd10 0001 SHA.L #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, 4); + imm =3D sign_ext (IMM(1), 8); + shift_op (dc, 1, imm, 1); +=20 + /* 1011 ddd w dd11 1110 SHA.size R1H,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + a =3D sign_ext (get_reg (r1h), 8); + shift_op (dc, 1, a, 1); +=20 + /* 1100 ddd0 dd01 0001 SHA.L R1H,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, 4); + a =3D sign_ext (get_reg (r1h), 8); + shift_op (dc, 1, a, 1); +=20 + /* 1100 ddd0 dd10 0001 SHANC.L #IMM,dest */ +=20 + M32C_ONLY(); + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, 4); + imm =3D sign_ext (IMM(1), 8); + shift_op (dc, 1, imm, 0); +=20 + /* 1110 ddd w dd00 immm SHL.size #IMM, dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + shift_op (dc, 0, IMM4(), 1); +=20 + /* 1001 ddd0 dd10 0001 SHL.L #IMM, dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, 4); + imm =3D sign_ext (IMM(1), 8); + shift_op (dc, 0, imm, 1); +=20 + /* 1010 ddd w dd11 1110 SHL.size R1H,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + a =3D sign_ext (get_reg (r1h), 8); + shift_op (dc, 0, a, 1); +=20 + /* 1100 ddd0 dd00 0001 SHL.L R1H,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, 4); + a =3D sign_ext (get_reg (r1h), 8); + shift_op (dc, 0, a, 1); +=20 + /* 1000 ddd0 dd10 0001 SHLNC.L #IMM,dest */ +=20 + M32C_ONLY(); + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, 4); + imm =3D sign_ext (IMM(1), 8); + shift_op (dc, 0, imm, 0); +=20 + /* 1011 0010 100w 0011 SIN.size */ +=20 + v =3D get_reg (a0); + a =3D get_reg (a1); + b =3D 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 +=3D w ? 2 : 1; + b --; + } + put_reg (a0, v); + put_reg (a1, a); + put_reg (r3, b); +=20 + /* 1011 0110 100w 0011 SMOVB.size */ +=20 + v =3D get_reg (a0); + a =3D get_reg (a1); + b =3D 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 -=3D w ? 2 : 1; + a -=3D w ? 2 : 1; + b --; + } + put_reg (a0, v); + put_reg (a1, a); + put_reg (r3, b); +=20 + /* 1011 0000 100w 0011 SMOVF.size */ +=20 + v =3D get_reg (a0); + a =3D get_reg (a1); + b =3D 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 +=3D w ? 2 : 1; + a +=3D w ? 2 : 1; + b --; + } + put_reg (a0, v); + put_reg (a1, a); + put_reg (r3, b); +=20 + /* 1011 1000 100w 0011 SMOVU.size */ +=20 + v =3D get_reg (a0); + a =3D get_reg (a1); + do + { + if (w) + mem_put_hi(a, (t0 =3D mem_get_hi (v))); + else + mem_put_qi(a, (t0 =3D mem_get_qi (v))); + v +=3D w ? 2 : 1; + a +=3D w ? 2 : 1; + if (t0 =3D=3D 0 + || (w && ((t0 & 0xff) =3D=3D 0 || (t0 & 0xff00) =3D=3D 0))) + break; + } while (1); + put_reg (a0, v); + put_reg (a1, a); +=20 + /* 1011 0100 100w 0011 SOUT.size */ +=20 + v =3D get_reg (a0); + a =3D get_reg (a1); + b =3D 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 +=3D w ? 2 : 1; + b --; + } + put_reg (a0, v); + put_reg (a1, a); + put_reg (r3, b); +=20 + /* 1011 1000 000w 0011 SSTR.size */ +=20 + a =3D get_reg (a1); + b =3D get_reg (r3); + for (;b;) + { + if (w) + mem_put_hi(a, r0); + else + mem_put_qi(a, r0 & 0xff); + a +=3D w ? 2 : 1; + b --; + } + put_reg (a1, a); + put_reg (r3, b); +=20 + /* 0000 0001 1101 ddd1 dd01 0src STC src,dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, 4); + sc =3D decode_cr_b (src, CR_B_DMA0); + a =3D get_src (sc); + put_dest (dc, a); +=20 + /* 0000 0001 1101 ddd1 dd01 1src STC src,dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, 2); + sc =3D decode_cr_b (src, CR_B_DCT0); + a =3D get_src (sc); + put_dest (dc, a); +=20 + /* 1101 ddd1 dd01 0src STC src,dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, 4); + sc =3D decode_cr_b (src, CR_B_INTB); + a =3D get_src (sc); + put_dest (dc, a); +=20 + /* 1011 0110 1101 0011 STCX abs16,abs24 */ +=20 + NOTYET(); +=20 + /* 1001 ddd w dd01 1111 STNZ.size #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + imm =3D IMM(w+1); + if (! FLAG_Z) + put_dest (dc, imm); +=20 + /* 1001 ddd w dd00 1111 STZ.size #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + imm =3D IMM(w+1); + if (FLAG_Z) + put_dest (dc, imm); +=20 + /* 1001 ddd w dd11 1111 STZX.size #IMM1,#IMM2,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + a =3D IMM(w+1); + b =3D IMM(w+1); + if (FLAG_Z) + put_dest (dc, a); + else + put_dest (dc, b); +=20 + /* 1000 ddd w dd11 1110 SUB.size:G #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23(ddd, dd, w+1); + imm =3D IMM(w+1); + MATH_OP (dc, imm, 0, -); +=20 + /* 1001 ddd0 dd11 0001 SUB.L:G #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23(ddd, dd, 4); + imm =3D IMM(4); + MATH_OP (dc, imm, 0, -); +=20 + /* 00dd 111w SUB.size:S #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest2(dd, w+1); + imm =3D IMM (w+1); + MATH_OP (dc, imm, 0, -); +=20 + /* 1sss ddd w dd ss 1010 SUB.size:G src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23(sss, ss, w+1); + dc =3D decode_dest23(ddd, dd, w+1); + b =3D get_src (sc); + MATH_OP (dc, b, 0, -); +=20 + /* 1sss ddd1 dd ss 0000 SUB.L:G src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23(sss, ss, 4); + dc =3D decode_dest23(ddd, dd, 4); + b =3D get_src (sc); + MATH_OP (dc, b, 0, -); +=20 + /* 1001 ddd0 dd01 0001 SUBX #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23(ddd, dd, 4); + imm =3D sign_ext (IMM(1), 8); + MATH_OP (dc, imm, 0, -); +=20 + /* 1sss ddd0 dd ss 0000 SUBX src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23(sss, ss, 1); + dc =3D decode_dest23(ddd, dd, 4); + b =3D sign_ext (get_src (sc), 8); + MATH_OP (dc, b, 0, -); +=20 + /* 1001 ddd w dd11 1110 TST.size:G #IMM,dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest23 (ddd, dd, w+1); + imm =3D IMM(w+1); + a =3D get_src (dc); + v =3D a & imm; + set_sz (v, w+1); +=20 + /* 00dd 110w TST.size:S #IMM,dest */ +=20 + prefix (0, 0, 0); + dc =3D decode_dest2 (dd, w+1); + imm =3D IMM(w+1); + a =3D get_src (dc); + v =3D a & imm; + set_sz (v, w+1); +=20 + /* 0000 0001 1sss ddd w dd ss 1001 TST.size:G src,dest */ +=20 + prefix (0, 0, 0); + sc =3D decode_src23 (sss, ss, w+1); + dc =3D decode_dest23 (ddd, dd, w+1); + b =3D get_src (sc); + a =3D get_src (dc); + v =3D a & b; + set_sz (v, w+1); +=20 + /* 1111 1111 UND */ +=20 + trigger_fixed_interrupt (0xffffdc); +=20 + /* 1011 0010 0000 0011 WAIT */ +=20 + ; +=20 + /* 1101 ddd w dd00 1src XCHG.size src,dest */ +=20 + dc =3D decode_dest23 (ddd, dd, w+1); + sc =3D decode_src3 (src, w+1); + a =3D get_src (dc); + b =3D get_src (sc); + put_dest (dc, b); + put_dest (sc, a); +=20 + /* 1001 ddd w dd00 1110 XOR.size #IMM,dest */ +=20 + prefix (0, 1, 0); + dc =3D decode_dest23(ddd, dd, w+1); + imm =3D IMM(w+1); + LOGIC_OP (dc, imm, ^); +=20 + /* 1sss ddd w dd ss 1001 XOR.size src,dest */ +=20 + prefix (1, 1, 0); + sc =3D decode_src23(sss, ss, w+1); + dc =3D decode_dest23(ddd, dd, w+1); + b =3D get_src (sc); + LOGIC_OP (dc, b, ^); +=20 + /* */ +=20 + return step_result; + } Index: sim/m32c/main.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 + #include + #include + #include + #include + #include + #include +=20 + #include "bfd.h" +=20 + #include "cpu.h" + #include "mem.h" + #include "misc.h" + #include "load.h" + #include "trace.h" +=20 + static int disassemble =3D 0; + static unsigned int cycles =3D 0; +=20 + static void + done(int exit_code) + { + if (verbose) + { + stack_heap_stats(); + mem_usage_stats(); + printf("insns: %14s\n", comma(cycles)); + } + exit(exit_code); + } +=20 + int + main(int argc, char **argv) + { + int o; + int save_trace; + bfd *prog; +=20 + while ((o =3D getopt(argc, argv, "tvdm:")) !=3D -1) + switch (o) + { + case 't': + trace ++; + break; + case 'v': + verbose ++; + break; + case 'd': + disassemble ++; + break; + case 'm': + if (strcmp (optarg, "r8c") =3D=3D 0 + || strcmp (optarg, "m16c") =3D=3D 0) + default_machine =3D bfd_mach_m16c; + else if (strcmp (optarg, "m32cm") =3D=3D 0 + || strcmp (optarg, "m32c") =3D=3D 0) + default_machine =3D 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] pro= gram\n"); + exit(1); + } +=20 + prog =3D bfd_openr (argv[optind], 0); + if (!prog) + { + fprintf(stderr, "Can't read %s\n", argv[optind]); + exit(1); + } +=20 + if (!bfd_check_format (prog, bfd_object)) + { + fprintf(stderr, "%s not a m32c program\n", argv[optind]); + exit(1); + } +=20 + save_trace =3D trace; + trace =3D 0; + m32c_load (prog); + trace =3D save_trace; +=20 + if (disassemble) + sim_disasm_init (prog); +=20 + while (1) + { + int rc; +=20 + if (trace) + printf("\n"); +=20 + if (disassemble) + sim_disasm_one(); +=20 + enable_counting =3D verbose; + cycles ++; + rc =3D decode_opcode (); + enable_counting =3D 0; +=20 + if (M32C_HIT_BREAK (rc)) + done(1); + else if (M32C_EXITED (rc)) + done(M32C_EXIT_STATUS (rc)); + else + assert (M32C_STEPPED (rc)); +=20 + trace_register_changes (); + } + } Index: sim/m32c/mem.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 + #include + #include +=20 + #include "mem.h" + #include "cpu.h" + #include "syscalls.h" + #include "misc.h" +=20 + #define L1_BITS (10) + #define L2_BITS (10) + #define OFF_BITS (12) +=20 + #define L1_LEN (1 << L1_BITS) + #define L2_LEN (1 << L2_BITS) + #define OFF_LEN (1 << OFF_BITS) +=20 + static unsigned char **pt[L1_LEN]; +=20 + /* [ get=3D0/put=3D1 ][ byte size ] */ + static unsigned int mem_counters[2][4]; +=20 + #define COUNT(isput,bytes) if (verbose && enable_counting) mem_counters[i= sput][bytes]++ +=20 + void + init_mem (void) + { + int i, j; +=20 + for (i =3D 0; i < L1_LEN; i++) + if (pt[i]) + { + for (j =3D 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)); + } +=20 + static unsigned char * + mem_ptr (address) + { + int pt1 =3D (address >> (L2_BITS + OFF_BITS)) & ((1 << L1_BITS) - 1); + int pt2 =3D (address >> OFF_BITS ) & ((1 << L2_BITS) - 1); + int pto =3D address & ((1 << OFF_BITS) - 1); +=20 + if (address =3D=3D 0) + { + printf("NULL pointer dereference\n"); + exit(1); + } +=20 + if (pt[pt1] =3D=3D 0) + pt[pt1] =3D (unsigned char **) calloc (L2_LEN, sizeof(char **)); + if (pt[pt1][pt2] =3D=3D 0) + { + pt[pt1][pt2] =3D (unsigned char *) malloc (OFF_LEN); + memset (pt[pt1][pt2], 0, OFF_LEN); + } +=20 + return pt[pt1][pt2] + pto; + } +=20 + static void + used (int rstart, int i, int j) + { + int rend =3D i << (L2_BITS + OFF_BITS); + rend +=3D j << OFF_BITS; + if (rstart =3D=3D 0xe0000 && rend =3D=3D 0xe1000) + return; + printf("mem: %08x - %08x (%dk bytes)\n", rstart, rend-1, (rend-rstart= )/1024); + } +=20 + static char * + mcs(int isput, int bytes) + { + return comma(mem_counters[isput][bytes]); + } +=20 + void + mem_usage_stats () + { + int i, j; + int rstart=3D0; + int pending =3D 0; +=20 + for (i =3D 0; i < L1_LEN; i++) + if (pt[i]) + { + for (j =3D 0; j < L2_LEN; j++) + if (pt[i][j]) + { + if (!pending) + { + pending =3D 1; + rstart =3D (i << (L2_BITS + OFF_BITS)) + (j << OFF_BITS); + } + } + else if (pending) + { + pending =3D 0; + used(rstart, i, j); + } + } + else + { + if (pending) + { + pending =3D 0; + used(rstart, i, 0); + } + } + /* mem foo: 123456789012 123456789012 123456789012 123456789012 12= 3456789012 */ + 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)); + } +=20 + static int tpr =3D 0; + static void + s (int address, char *dir) + { + if (tpr =3D=3D 0) + printf("MEM[%0*x] %s", membus_mask =3D=3D 0xfffff ? 5 : 6, address, d= ir); + tpr++; + } + #define S(d) if (trace) s(address, d) + static void + e() + { + if (!trace) + return; + tpr--; + if (tpr =3D=3D 0) + printf("\n"); + } + #define E() if (trace) e() +=20 + void + mem_put_byte (int address, unsigned char value) + { + unsigned char *m; + address &=3D membus_mask; + m =3D mem_ptr(address); + if (trace) + printf(" %02x", value); + *m =3D value; + switch (address) + { + case 0x00e1: + { + static int old_led =3D -1; + static char *led_on[] =3D {"\033[31m O ", "\033[32m O ", "\033[34m O "}; + static char *led_off[] =3D {"\033[0m =C2=B7 ", "\033[0m =C2=B7 ", "\033[= 0m =C2=B7 "}; + int i; + if (old_led !=3D value) + { + fputs(" ", stdout); + for (i=3D0; i<3; i++) + if (value & (1<> 8); + E (); + COUNT(1,2); + } +=20 + void + mem_put_psi (int address, unsigned long value) + { + S ("<=3D"); + 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); + } +=20 + void + mem_put_si (int address, unsigned long value) + { + S("<=3D"); + 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); + } +=20 + void + mem_put_blk (int address, void *bufptr, int nbytes) + { + S("<=3D"); + if (enable_counting) + mem_counters[1][1] +=3D nbytes; + while (nbytes--) + mem_put_byte (address++, *(unsigned char *)bufptr++); + E(); + } +=20 + unsigned char + mem_get_pc () + { + unsigned char *m =3D mem_ptr(regs.r_pc & membus_mask); + COUNT(0,0); + return *m; + } +=20 + static unsigned char + mem_get_byte (int address) + { + unsigned char *m; + address &=3D membus_mask; + S("=3D>"); + m =3D mem_ptr(address); + if (trace) + { + if (tpr) + printf(" %02x", *m); + else + { + S("=3D>"); + printf(" %02x", *m); + E(); + } + } + E(); + return *m; + } +=20 + unsigned char + mem_get_qi (int address) + { + unsigned char rv; + S("=3D>"); + rv =3D mem_get_byte (address); + COUNT(0,1); + E(); + return rv; + } +=20 + unsigned short + mem_get_hi (int address) + { + unsigned short rv; + S("=3D>"); + rv =3D mem_get_byte (address); + rv |=3D mem_get_byte (address+1) * 256; + COUNT(0,2); + E(); + return rv; + } +=20 + unsigned long + mem_get_psi (int address) + { + unsigned long rv; + S("=3D>"); + rv =3D mem_get_byte (address); + rv |=3D mem_get_byte (address+1) * 256; + rv |=3D mem_get_byte (address+2) * 65536; + COUNT(0,3); + E(); + return rv; + } +=20 + unsigned long + mem_get_si (int address) + { + unsigned long rv; + S("=3D>"); + rv =3D mem_get_byte (address); + rv |=3D mem_get_byte (address + 1) << 8; + rv |=3D mem_get_byte (address + 2) << 16; + rv |=3D mem_get_byte (address + 3) << 24; + COUNT(0,4); + E(); + return rv; + } +=20 + void + mem_get_blk (int address, void *bufptr, int nbytes) + { + S("=3D>"); + if (enable_counting) + mem_counters[0][1] +=3D nbytes; + while (nbytes--) + *(char *)bufptr++ =3D mem_get_byte (address++); + E(); + } +=20 + int + sign_ext(int v, int bits) + { + if (bits < 32) + { + v &=3D (1< +=20 + #include "cpu.h" + #include "misc.h" +=20 + int + bcd2int (int bcd, int w) + { + int v=3D0, m=3D1, i; + for (i =3D 0; i < (w ? 4 : 2); i++) + { + v +=3D (bcd % 16) * m; + m *=3D 10; + bcd /=3D 16; + } + return v; + } +=20 + int + int2bcd (int v, int w) + { + int bcd=3D0, m=3D1, i; + for (i =3D 0; i < (w ? 4 : 2); i++) + { + bcd +=3D (v % 10) * m; + m *=3D 16; + v /=3D 10; + } + return bcd; + } +=20 + char * + comma(unsigned int u) + { + static char buf[5][20]; + static int bi =3D 0; + int comma=3D0; + char *bp; +=20 + bi =3D (bi+1) % 5; + bp =3D buf[bi] + 19; + *--bp =3D 0; + do { + if (comma =3D=3D 3) + { + *--bp =3D ','; + comma =3D 0; + } + comma ++; + *--bp =3D '0' + (u % 10); + u /=3D 10; + } while (u); + return bp; + } Index: sim/m32c/misc.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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); +=20 + char *comma (unsigned int u); Index: sim/m32c/opc2c.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 + #include + #include + #include +=20 + #include "safe-fgets.h" +=20 + static int errors =3D 0; +=20 + #define MAX_BYTES 10 +=20 + typedef struct { + int varyno:16; + int byte:8; + int shift:8; + } VaryRef; +=20 + 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; +=20 + int n_opcodes; + opcode **opcodes; + opcode *op; +=20 + typedef struct { + char *name; + int nlen; + unsigned char mask; + int n_patterns; + unsigned char *patterns; + } Vary; +=20 + Vary **vary =3D 0; + int n_varies =3D 0; +=20 + unsigned char cur_bits[MAX_BYTES+1]; +=20 + char *orig_filename; +=20 + FILE *sim_log =3D 0; + #define lprintf if (sim_log) fprintf +=20 + opcode prefix_text, suffix_text; +=20 + typedef enum { + T_unused, + T_op, + T_indirect, + T_done + } OpType; +=20 + typedef struct Indirect { + OpType type; + union { + struct Indirect *ind; + opcode *op; + } u; + } Indirect; +=20 + Indirect indirect[256]; +=20 + static int + next_varybits (int bits, opcode *op, int byte) + { + int mask =3D op->b[byte].decodable_mask; + int i; +=20 + for (i=3D0; i<8; i++) + if (!(mask & (1<nvaries) + { + int vn; + for (vn=3D0; vnnvaries; vn++) + { + int found =3D 0; + int i; + int ob; +=20 + if (byte !=3D op->vary[vn].byte) + continue; + Vary *v =3D vary[op->vary[vn].varyno]; + ob =3D (bits >> op->vary[vn].shift) & v->mask; + lprintf(sim_log, "varybits: vary %s ob %x\n", v->name, ob); +=20 + for (i=3D0; in_patterns; i++) + if (ob =3D=3D v->patterns[i]) + { + lprintf(sim_log, " found at %d\n", i); + found =3D 1; + break; + } + if (!found) + return 0; + } + } + return 1; + } +=20 + char * + prmb (int mask, int bits) + { + static char buf[8][30]; + static int bn =3D 0; + char *bp; +=20 + bn =3D (bn+1) % 8; + bp =3D buf[bn]; + int i; + for (i=3D0; i<8; i++) + { + int bit =3D 0x80 >> i; + if (! (mask & bit)) + *bp++ =3D '-'; + else if (bits & bit) + *bp++ =3D '1'; + else + *bp++ =3D '0'; + if (i % 4 =3D=3D 3) + *bp++ =3D ' '; + } + *--bp =3D 0; + return buf[bn]; + } +=20 + static int + op_cmp (const void *va, const void *vb) + { + const opcode *a =3D *(const opcode **)va; + const opcode *b =3D *(const opcode **)vb; +=20 + if (a->nbytes !=3D b->nbytes) + return a->nbytes - b->nbytes; +=20 + return strcmp (a->id, b->id); + } +=20 + void + dump_lines (opcode *op, int level, Indirect *ind) + { + char *varnames[40]; + int i, vn=3D0; +=20 + if (op->semantics_label) + { + printf("%*sgoto op_semantics_%d;\n", level, "", op->semantics_label= ); + return; + } +=20 + if (ind !=3D op->last_ind) + { + static int labelno =3D 0; + labelno ++; + printf("%*sop_semantics_%d:\n", level, "", labelno); + op->semantics_label =3D labelno; + } +=20 + if (op->comment) { + level +=3D 2; + printf("%*s{\n", level, ""); + printf("%*s %s\n", level, "", op->comment); + } +=20 + for (i=3D0; inbytes*8;) + { + if (isalpha(op->id[i])) + { + int byte =3D i >> 3; + int mask =3D 0; + int shift =3D 0; + char name[33]; + char *np =3D name; + while (op->id[i] && isalpha(op->id[i])) + { + mask =3D (mask << 1) | 1; + shift =3D 7 - (i & 7); + *np++ =3D op->id[i++]; + if (op->var_start[i]) + break; + } + *np =3D 0; + varnames[vn++] =3D 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 !=3D 0xff)) + printf("%*s int %s AU =3D (op[%d] >> %d) & 0x%02x;\n", + level, "", name, byte, shift, mask); + else if (mask !=3D 0xff) + printf("%*s int %s AU =3D op[%d] & 0x%02x;\n", + level, "", name, byte, mask); + else + printf("%*s int %s AU =3D 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=3D0; inbytes; i++) + printf(" %%02x"); + printf("\\n\""); + printf(",\n%*s \"%s\"", level, "", op->comment); + for (i=3D0; inbytes; i++) + { + if (i =3D=3D 0) + printf(",\n%*s op[%d]", level, "", i); + else + printf(", op[%d]", i); + } + printf(");\n"); + for (i=3D0; ilineno+1, orig_filename); + for (i=3D0; inlines; i++) + printf("%*s%s", level, "", op->lines[i]); + if (op->comment) + printf("%*s}\n", level, ""); + } +=20 + void + store_opcode_bits (opcode *op, int byte, Indirect *ind) + { + int bits =3D op->b[byte].decodable_bits; +=20 + do { + if (!valid_varybits (bits, op, byte)) + continue; +=20 + switch (ind[bits].type) + { + case T_unused: + if (byte =3D=3D op->dbytes-1) + { + ind[bits].type =3D T_op; + ind[bits].u.op =3D op; + op->last_ind =3D ind; + break; + } + else + { + int i2; + ind[bits].type =3D T_indirect; + ind[bits].u.ind =3D (Indirect *)malloc (256*sizeof(Indirect)); + for (i2=3D0; i2<256; i2++) + ind[bits].u.ind[i2].type =3D T_unused; + store_opcode_bits (op, byte+1, ind[bits].u.ind); + } + break; +=20 + case T_indirect: + if (byte < op->dbytes-1) + store_opcode_bits (op, byte+1, ind[bits].u.ind); + break; +=20 + case T_op: + break; +=20 + case T_done: + break; + } + } while ((bits =3D next_varybits (bits, op, byte)) !=3D 0); + } +=20 + void + emit_indirect (Indirect *ind, int byte) + { + int unsup =3D 0; + int j, n, mask; +=20 + mask =3D 0; + for (j=3D0; j<256; j++) + { + switch (ind[j].type) + { + case T_indirect: + mask =3D 0xff; + break; + case T_op: + mask |=3D ind[j].u.op->b[byte].decodable_mask; + break; + case T_done: + case T_unused: + break; + } + } +=20 + printf("%*s GETBYTE();\n", byte*6, ""); + printf("%*s switch (op[%d] & 0x%02x) {\n", byte*6, "", byte, mask); + for (j=3D0; j<256; j++) + if ((j & ~mask) =3D=3D 0) + { + switch (ind[j].type) + { + case T_done: + break; + case T_unused: + unsup =3D 1; + break; + case T_op: + for (n =3D j; n < 256; n++) + if ((n & ~mask) =3D=3D 0 + && ind[n].type =3D=3D T_op + && ind[n].u.op =3D=3D ind[j].u.op) + { + ind[n].type =3D T_done; + printf("%*s case 0x%02x:\n", byte*6, "", n); + } + for (n=3Dbyte; nnbytes-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, ""); + } +=20 + static char * + pv_dup (char *p, char *ep) + { + int n =3D ep - p; + char *rv =3D (char *) malloc (n + 1); + memcpy (rv, p, n); + rv[n] =3D 0; + return rv; + } +=20 + static unsigned char + str2mask (char *str, char *ep) + { + unsigned char rv =3D 0; + while (str < ep) + { + rv *=3D 2; + if (*str =3D=3D '1') + rv +=3D 1; + str ++; + } + return rv; + } +=20 + static void + process_vary (char *line) + { + char *cp, *ep; + Vary *v =3D (Vary *) malloc (sizeof (Vary)); +=20 + n_varies ++; + if (vary) + vary =3D (Vary **) realloc (vary, n_varies * sizeof (Vary *)); + else + vary =3D (Vary **) malloc (n_varies * sizeof (Vary *)); + vary[n_varies-1] =3D v; +=20 + cp =3D line; +=20 + for (cp =3D line; isspace(*cp); cp++) ; + for (ep=3Dcp; *ep && !isspace(*ep); ep++) ; +=20 + v->name =3D pv_dup (cp, ep); + v->nlen =3D strlen (v->name); + v->mask =3D (1 << v->nlen) - 1; +=20 + v->n_patterns =3D 0; + v->patterns =3D (unsigned char *) malloc (1); + while (1) + { + for (cp =3D ep; isspace(*cp); cp++) ; + if (! isdigit (*cp)) + break; + for (ep=3Dcp; *ep && !isspace(*ep); ep++) ; + v->n_patterns ++; + v->patterns =3D (unsigned char *) realloc (v->patterns, v->n_patter= ns); + v->patterns[v->n_patterns-1] =3D str2mask (cp, ep); + } + } +=20 + static int + fieldcmp (opcode *op, int bit, char *name) + { + int n =3D strlen (name); + if (memcmp (op->id + bit, name, n) =3D=3D 0 + && (!isalpha(op->id[bit+n]) + || op->var_start[bit+n])) + return 1; + return 0; + } +=20 + static void + log_indirect (Indirect *ind, int byte) + { + int i, j; + char *last_c =3D 0; +=20 + for (i=3D0; i<256; i++) + { + if (ind[i].type =3D=3D T_unused) + continue; +=20 + for (j=3D0; jcomment =3D=3D last_c)) + fprintf(sim_log, "''\n"); + else + fprintf(sim_log, "%s\n", ind[i].u.op->comment); + last_c =3D 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] =3D i; + log_indirect (ind[i].u.ind, byte+1); + last_c =3D 0; + break; + } + } + } +=20 + int + main(int argc, char **argv) + { + char *line; + FILE *in; + int lineno =3D 0; + int i; + VaryRef *vlist; +=20 + if (argc > 2 && strcmp (argv[1], "-l") =3D=3D 0) + { + sim_log =3D fopen(argv[2], "w"); + fprintf(stderr, "sim_log: %s\n", argv[2]); + argc -=3D 2; + argv +=3D 2; + } +=20 + if (argc < 2) + { + fprintf(stderr, "usage: opc2c infile.opc > outfile.opc\n"); + exit(1); + } +=20 + orig_filename =3D argv[1]; + in =3D fopen (argv[1], "r"); + if (!in) + { + fprintf(stderr, "Unable to open file %s for reading\n", argv[1]); + perror("The error was"); + exit(1); + } +=20 + n_opcodes =3D 0; + opcodes =3D (opcode **)malloc(sizeof(opcode *)); + op =3D &prefix_text; + op->lineno =3D 1; + while ((line =3D safe_fgets (in)) !=3D 0) + { + lineno ++; + if (strncmp (line, " /* ", 5) =3D=3D 0 + && (isdigit (line[5]) || memcmp (line+5, "VARY", 4) =3D=3D 0)) + line +=3D 2; + if (line[0] =3D=3D '/' && line[1] =3D=3D '*') + { + if (strncmp (line, "/* */", 5) =3D=3D 0) + { + op =3D &suffix_text; + op->lineno =3D lineno; + } + else if (strncmp (line, "/* VARY ", 8) =3D=3D 0) + process_vary (line+8); + else + { + char *lp; + int i, bit, byte; + int var_start =3D 1; +=20 + n_opcodes ++; + opcodes =3D (opcode **) realloc (opcodes, n_opcodes * sizeof (opco= de *)); + op =3D (opcode *) malloc (sizeof (opcode)); + opcodes[n_opcodes - 1] =3D op; +=20 + op->nbytes =3D op->dbytes =3D 0; + memset (op->id, 0, sizeof(op->id)); + memset (op->var_start, 0, sizeof(op->var_start)); + for (i=3D0; ib[i].decodable_mask =3D 0; + op->b[i].decodable_bits =3D 0; + } + op->comment =3D strdup (line); + op->comment[strlen(op->comment)-1] =3D 0; + while (op->comment[0] && isspace (op->comment[0])) + op->comment ++; + op->lineno =3D lineno; + op->nlines =3D 0; + op->lines =3D 0; + op->last_ind =3D 0; + op->semantics_label =3D 0; + op->nvaries =3D 0; + op->vary =3D 0; +=20 + i =3D 0; + for (lp =3D line+3; *lp; lp++) + { + bit =3D 7 - (i & 7); + byte =3D i >> 3; +=20 + if (strncmp (lp, "*/", 2) =3D=3D 0) + break; + else if ((lp[0] =3D=3D ' ' && lp[1] =3D=3D ' ') || (lp[0] =3D=3D '\t'= )) + break; + else if (*lp =3D=3D ' ') + var_start =3D 1; + else + { + if (*lp =3D=3D '0' || *lp =3D=3D '1') + { + op->b[byte].decodable_mask |=3D 1 << bit; + var_start =3D 1; + if (op->dbytes < byte+1) + op->dbytes =3D byte+1; + } + else if (var_start) + { + op->var_start[i] =3D 1; + var_start =3D 0; + } + if (*lp =3D=3D '1') + op->b[byte].decodable_bits |=3D 1 << bit; +=20 + op->nbytes =3D byte + 1; + op->id[i++] =3D *lp; + } + } + } + } + else + { + op->nlines ++; + if (op->lines) + op->lines =3D (char **) realloc (op->lines, op->nlines * sizeof (cha= r *)); + else + op->lines =3D (char **) malloc (op->nlines * sizeof (char *)); + op->lines[op->nlines-1] =3D strdup (line); + } + } +=20 + { + int i, j; + for (i=3D0; iname, v->nlen); + for (j=3D0; jn_patterns; j++) + lprintf(sim_log, " P %02x\n", v->patterns[j]); + } + } +=20 + for (i=3Dn_opcodes-2; i>=3D 0; i--) + { + if (opcodes[i]->nlines =3D=3D 0) + { + opcodes[i]->nlines =3D opcodes[i+1]->nlines; + opcodes[i]->lines =3D opcodes[i+1]->lines; + } + } +=20 + for (i=3D0; i<256; i++) + indirect[i].type =3D T_unused; +=20 + qsort (opcodes, n_opcodes, sizeof(opcodes[0]), op_cmp); +=20 + vlist =3D (VaryRef *) malloc (n_varies * sizeof (VaryRef)); +=20 + for (i=3D0; inbytes; 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); +=20 + for (j=3D0; jnbytes; j++) + { + for (b=3D0; b<8; b++) + if (isalpha (opcodes[i]->id[j*8+b])) + for (v=3D0; vname)) + { + int nv =3D opcodes[i]->nvaries ++; + if (nv) + opcodes[i]->vary =3D (VaryRef *) realloc (opcodes[i]->vary, (nv+1= ) * sizeof(VaryRef)); + else + opcodes[i]->vary =3D (VaryRef *) malloc ((nv+1) * sizeof(VaryRef)= ); +=20 + opcodes[i]->vary[nv].varyno =3D v; + opcodes[i]->vary[nv].byte =3D j; + opcodes[i]->vary[nv].shift =3D 8 - b - vary[v]->nlen; + lprintf(sim_log, "[vary %s shift %d]\n", + vary[v]->name, opcodes[i]->vary[nv].shift); + } +=20=09=09=09=20=20 + } + } +=20 + for (i=3D0; idbytes; +=20 + lprintf (sim_log, "\nmask:"); + for (i2=3D0; i2nbytes; 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); +=20 + lprintf (sim_log, "bits:"); + for (i2=3D0; i2nbytes; 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=3D=3D1 ? "" : "s"); +=20 + store_opcode_bits (opcodes[i], 0, indirect); + } +=20 + dump_lines (&prefix_text, 0, 0); +=20 + emit_indirect (indirect, 0); +=20 + dump_lines (&suffix_text, 0, 0); +=20 + if (sim_log) + log_indirect (indirect, 0); +=20 + return errors; + } Index: sim/m32c/r8c.opc =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 /* -*- mode: c -*- */ + #include +=20 + #include "cpu.h" + #include "mem.h" + #include "misc.h" + #include "int.h" +=20 + #define AU __attribute__((unused)) +=20 + #define tprintf if (trace) printf +=20 + static unsigned char + getbyte () + { + int tsave =3D trace; + unsigned char b; +=20 + if (trace =3D=3D 1) + trace =3D 0; + b =3D mem_get_pc (); + regs.r_pc ++; + trace =3D tsave; + return b; + } +=20 + #define M16C_ONLY() /* FIXME: add something here */ +=20 + #define GETBYTE() (op[opi++] =3D getbyte()) +=20 + #define UNSUPPORTED() unsupported("unsupported", orig_pc) + #define NOTYET() unsupported("unimplemented", orig_pc) +=20 + static void + unsupported (char *tag, int orig_pc) + { + int i; + printf("%s opcode at %08x\n", tag, orig_pc); + regs.r_pc =3D orig_pc; + for (i=3D0; i<2; i++) + { + int b =3D mem_get_pc(); + printf(" %s", bits(b>>4, 4)); + printf(" %s", bits(b, 4)); + regs.r_pc ++; + } + printf("\n"); + regs.r_pc =3D orig_pc; + for (i=3D0; i<6; i++) + { + printf(" %02x", mem_get_pc ()); + regs.r_pc ++; + } + printf("\n"); + exit(1); + } +=20 + static int + IMM(bw) + { + int rv =3D getbyte (); + if (bw) + rv =3D rv + 256 * getbyte(); + if (bw =3D=3D 2) + rv =3D rv + 65536 * getbyte(); + return rv; + } +=20 + #define IMM4() (immm >=3D 8 ? 7 - immm : immm + 1) +=20 + #define UNARY_SOP \ + dc =3D decode_srcdest4 (dest, w); \ + v =3D sign_ext (get_src (dc), w?16:8); +=20 + #define UNARY_UOP \ + dc =3D decode_srcdest4 (dest, w); \ + v =3D get_src (dc); +=20 + #define BINARY_SOP \ + sc =3D decode_srcdest4 (srcx, w); \ + dc =3D decode_srcdest4 (dest, w); \ + a =3D sign_ext (get_src (sc), w?16:8); \ + b =3D sign_ext (get_src (dc), w?16:8); +=20 + #define BINARY_UOP \ + sc =3D decode_srcdest4 (srcx, w); \ + dc =3D decode_srcdest4 (dest, w); \ + a =3D get_src (sc); \ + b =3D get_src (dc); +=20 + #define carry (FLAG_C ? 1 : 0) +=20 + static void + cmp (int d, int s, int w) + { + int a, b, f=3D0; + int mask =3D w ? 0xffff : 0xff; + a =3D d - s; + b =3D sign_ext (d, w?16:8) - sign_ext (s, w?16:8); + tprintf ("cmp: %x - %x =3D %08x, %x - %x =3D %d\n", + d, s, a, + sign_ext(d,w?16:8), sign_ext(s,w?16:8), b); +=20 + if (b =3D=3D 0) + f |=3D FLAGBIT_Z; + if (b & (w ? 0x8000 : 0x80)) + f |=3D FLAGBIT_S; + if ((d & mask) >=3D (s & mask)) + f |=3D FLAGBIT_C; + if (b < (w ? -32768 : -128) || b > (w ? 32767 : 127)) + f |=3D FLAGBIT_O; +=20 + set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f); + } +=20 + static void + div_op (int s, int u, int x, int w) + { + srcdest sc; + int v, a, b; +=20 + if (s =3D=3D -1) + s =3D IMM(w); + else + { + sc =3D decode_srcdest4 (s, w); + s =3D get_src (sc); + } +=20 + v =3D get_reg (w ? r2r0 : r0); +=20 + if (!u) + { + s =3D sign_ext (s, w ? 16 : 8); + v =3D sign_ext (v, w ? 16 : 8); + } +=20 + if (s =3D=3D 0) + { + set_flags (FLAGBIT_O, FLAGBIT_O); + return; + } +=20 + if (u) + { + a =3D (unsigned int)v / (unsigned int)s; + b =3D (unsigned int)v % (unsigned int)s; + } + else + { + a =3D v / s; + b =3D v % s; + } + if (x) + { + if ((s > 0 && b < 0) + || (s < 0 && b > 0)) + { + a --; + b +=3D s; + } + } + tprintf ("%d / %d =3D %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); +=20 + put_reg (w ? r0 : r0l, a); + put_reg (w ? r2 : r0h, b); + } +=20 + static void + rot_op (srcdest sd, int rotc, int count) + { + int mask =3D (sd.bytes =3D=3D 2) ? 0xffff : 0xff; + int msb =3D (sd.bytes =3D=3D 2) ? 0x8000 : 0x80; + int v =3D get_src (sd); + int c =3D carry, ct; +=20 + 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 =3D (v & msb) ? 1 : 0; + v <<=3D 1; + v |=3D rotc ? c : ct; + v &=3D mask; + c =3D ct; + tprintf (": %s %d\n", bits(v, 8*sd.bytes), c); + count --; + } + while (count < 0) + { + ct =3D v & 1; + v >>=3D 1; + v |=3D (rotc ? c : ct) * msb; + c =3D ct; + tprintf (": %s %d\n", bits(v, 8*sd.bytes), c); + count ++; + } + put_dest (sd, v); + set_szc (v, sd.bytes, c); + } +=20 + static void + shift_op (srcdest sd, int arith, int count) + { + int mask =3D (sd.bytes =3D=3D 2) ? 0xffff : 0xff; + int msb =3D (sd.bytes =3D=3D 2) ? 0x8000 : 0x80; + int v =3D get_src (sd); + int c =3D 0; +=20 + if (sd.bytes =3D=3D 4) + { + mask =3D 0xffffffffU; + msb =3D 0x80000000U; + } +=20 + 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 =3D (v & msb) ? 1 : 0; + v <<=3D 1; + v &=3D mask; + tprintf (": %s %d\n", bits(v, 8*sd.bytes), c); + count --; + } + while (count < 0) + { + c =3D v & 1; + if (arith) + v =3D (v & msb) | (v >> 1); + else + v =3D (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); + } +=20 + #define MATH_OP(dc,s,c,op,carryrel) \ + a =3D get_src(dc); \ + b =3D s & b2mask[dc.bytes]; \ + v2 =3D a op b op c; \ + tprintf("0x%x " #op " 0x%x " #op " 0x%x =3D 0x%x\n", a, b, c, v2); \ + a =3D sign_ext (a, dc.bytes * 8); \ + b =3D sign_ext (s, dc.bytes * 8); \ + v =3D a op b op c; \ + tprintf("%d " #op " %d " #op " %d =3D %d\n", a, b, c, v); \ + set_oszc (v, dc.bytes, v2 carryrel); \ + put_dest (dc, v2); +=20 + #define BIT_OP(field,expr) \ + dc =3D decode_bit (field); \ + b =3D get_bit (dc); \ + v =3D expr; \ + tprintf ("b=3D%d, carry=3D%d, %s =3D %d\n", b, carry, #expr, v); \ + put_bit (dc, v); +=20 + #define BIT_OPC(field,expr) \ + dc =3D decode_bit (field); \ + b =3D get_bit (dc); \ + v =3D expr; \ + tprintf ("b=3D%d, carry=3D%d, %s =3D %d\n", b, carry, #expr, v); \ + set_c (v); +=20 + int + decode_r8c() + { + unsigned char op[40]; + int opi =3D 0; + int v, v2, a, b; + int orig_pc =3D get_reg (pc); + srcdest sc, dc; + int imm; +=20 + step_result =3D M32C_MAKE_STEPPED (); +=20 + tprintf("trace: decode pc =3D %05x\n", orig_pc); +=20 + /* VARY dst 011 100 101 110 111 */ +=20 + /* 0111 011w 1111 dest ABS.size dest */ +=20 + UNARY_SOP; + a =3D v<0 ? -v : v; + tprintf("abs(%d) =3D %d\n", v, a); + set_osz(a, w+1); + put_dest (dc, a); +=20 + /* 0111 011w 0110 dest ADC.size #IMM,dest */ +=20 + dc =3D decode_srcdest4(dest, w); + imm =3D IMM(w); + MATH_OP (dc, imm, carry, +, > (w?0xffff:0xff)); +=20 + /* 1011 000w srcx dest ADC.size src,dest */ +=20 + sc =3D decode_srcdest4(srcx, w); + dc =3D decode_srcdest4(dest, w); + b =3D get_src (sc); + MATH_OP (dc, b, carry, +, > (w?0xffff:0xff)); +=20 + /* 0111 011w 1110 dest ADCF.size dest */ +=20 + dc =3D decode_srcdest4(dest, w); + MATH_OP (dc, 0, carry, +, > (w?0xffff:0xff)); +=20 + /* 0111 011w 0100 dest ADD.size:G #imm,dest */ +=20 + dc =3D decode_srcdest4(dest, w); + imm =3D IMM(w); + MATH_OP (dc, imm, 0, +, > (w?0xffff:0xff)); +=20 + /* 1100 100w immm dest ADD.size:Q #IMM,dest */ +=20 + dc =3D decode_srcdest4(dest, w); + imm =3D sign_ext (immm, 4); + MATH_OP (dc, imm, 0, +, > (w?0xffff:0xff)); +=20 + /* 1000 0dst ADD.B:S #IMM8,dst */ +=20 + imm =3D IMM(0); + dc =3D decode_dest3 (dst, 0); + MATH_OP (dc, imm, 0, +, > 0xff); +=20 + /* 1010 000w srcx dest ADD.size:G src,dest */ +=20 + sc =3D decode_srcdest4(srcx, w); + dc =3D decode_srcdest4(dest, w); + b =3D get_src (sc); + MATH_OP (dc, b, 0, +, > (w?0xffff:0xff)); +=20 + /* 0010 0d sr ADD.B:S src,R0L/R0H */ +=20 + sc =3D decode_src2 (sr, 0, d); + dc =3D decode_dest1 (d, 0); + b =3D get_src (sc); + MATH_OP (dc, b, 0, +, > 0xff); +=20 + /* 0111 110w 1110 1011 ADD.size:G #IMM,sp */ +=20 + dc =3D reg_sd (sp); + imm =3D sign_ext (IMM(w), w?16:8); + MATH_OP (dc, imm, 0, +, > 0xffff); +=20 + /* 0111 1101 1011 immm ADD.size:Q #IMM,sp */ +=20 + dc =3D reg_sd (sp); + imm =3D sign_ext (immm, 4); + MATH_OP (dc, imm, 0, +, > 0xffff); +=20 + /* 1111 100w immm dest ADJNZ.size #IMM,dest,label */ +=20 + UNARY_UOP; + imm =3D sign_ext(immm, 4); + tprintf("%x + %d =3D %x\n", v, imm, v+imm); + v +=3D imm; + put_dest (dc, v); + a =3D sign_ext (IMM(0), 8); + if ((v & (w ? 0xffff : 0xff)) !=3D 0) + { + tprintf("jmp: %x + 2 + %d =3D ", get_reg (pc), a); + put_reg (pc, orig_pc + 2 + a); + tprintf("%x\n", get_reg (pc)); + } +=20 + /* 0111 011w 0010 dest AND.size:G #IMM,dest */ +=20 + UNARY_UOP; + imm =3D IMM(w); + tprintf ("%x & %x =3D %x\n", v, imm, v & imm); + v &=3D imm; + set_sz (v, w+1); + put_dest (dc, v); +=20 + /* 1001 0dst AND.B:S #IMM8,dest */ +=20 + imm =3D IMM(0); + dc =3D decode_dest3 (dst, 0); + v =3D get_src (dc); + tprintf("%x & %x =3D %x\n", v, imm, v & imm); + v &=3D imm; + set_sz (v, 1); + put_dest (dc, v); +=20 + /* 1001 000w srcx dest AND.size:G src.dest */ +=20 + BINARY_UOP; + tprintf ("%x & %x =3D %x\n", a, b, a & b); + v =3D a & b; + set_sz (v, w+1); + put_dest (dc, v); +=20 + /* 0001 0d sr AND.B:S src,R0L/R0H */ +=20 + sc =3D decode_src2 (sr, 0, d); + dc =3D decode_dest1 (d, 0); + a =3D get_src (sc); + b =3D get_src (dc); + v =3D a & b; + tprintf("%x & %x =3D %x\n", a, b, v); + set_sz (v, 1); + put_dest (dc, v); +=20 + /* 0111 1110 0100 srcx BAND src */ +=20 + BIT_OPC (srcx, b & carry); +=20 + /* 0111 1110 1000 dest BCLR:G dest */ +=20 + dc =3D decode_bit (dest); + put_bit (dc, 0); +=20 + /* 0100 0bit BCLR:S bit,base:11[SB] */ +=20 + dc =3D decode_bit11 (bit); + put_bit (dc, 0); +=20 + /* 0111 1110 0010 dest BMcnd dest */ +=20 + dc =3D decode_bit (dest); + if (condition_true (IMM (0))) + put_bit (dc, 1); + else + put_bit (dc, 0); +=20 + /* 0111 1101 1101 cond BMcnd C */ +=20 + if (condition_true (cond)) + set_c (1); + else + set_c (0); +=20 + /* 0111 1110 0101 srcx BNAND src */ +=20 + BIT_OPC (srcx, !b & carry); +=20 + /* 0111 1110 0111 srcx BNOR src */ +=20 + BIT_OPC (srcx, !b | carry); +=20 + /* 0111 1110 1010 dest BNOT:G dest */ +=20 + BIT_OP (dest, !b); +=20 + /* 0101 0bit BNOT:S bit,base:11[SB] */ +=20 + dc =3D decode_bit11 (bit); + put_bit (dc, !get_bit (dc)); +=20 + /* 0111 1110 0011 srcx BNTST src */ +=20 + dc =3D decode_bit (srcx); + b =3D get_bit (dc); + set_zc (!b, !b); +=20 + /* 0111 1110 1101 srcx BNXOR src */ +=20 + BIT_OPC (srcx, !b ^ carry); +=20 + /* 0111 1110 0110 srcx BOR src */ +=20 + BIT_OPC (srcx, b | carry); +=20 + /* 0000 0000 BRK */ +=20 + /* We report the break to our caller with the PC still pointing at the= =20 + breakpoint instruction. */ + put_reg (pc, orig_pc); + if (verbose) + printf("[break]\n"); + return M32C_MAKE_HIT_BREAK (); +=20 + /* 0111 1110 1001 dest BSET:G dest */ +=20 + dc =3D decode_bit (dest); + put_bit (dc, 1); +=20 + /* 0100 1bit BSET:S bit,base:11[SB] */ +=20 + dc =3D decode_bit11 (bit); + put_bit (dc, 1); +=20 + /* 0111 1110 1011 srcx BTST:G src */ +=20 + dc =3D decode_bit (srcx); + b =3D get_bit (dc); + set_zc (!b, b); +=20 + /* 0101 1bit BTST:S bit,base:11[SB] */ +=20 + dc =3D decode_bit11 (bit); + b =3D get_bit (dc); + set_zc (!b, b); +=20 + /* 0111 1110 0000 dest BTSTC dest */ +=20 + dc =3D decode_bit (dest); + b =3D get_bit (dc); + set_zc (!b, b); + put_bit (dc, 0); +=20 + /* 0111 1110 0001 dest BTSTS dest */ +=20 + dc =3D decode_bit (dest); + b =3D get_bit (dc); + set_zc (!b, b); + put_bit (dc, 1); +=20 + /* 0111 1110 1100 srcx BXOR src */ +=20 + BIT_OPC (srcx, b ^ carry); +=20 + /* 0111 011w 1000 dest CMP.size:G #IMM,dest */ +=20 + UNARY_UOP; + imm =3D IMM(w); + cmp (v, imm, w); +=20 + /* 1101 000w immm dest CMP.size:Q #IMM,dest */ +=20 + UNARY_UOP; + immm =3D sign_ext (immm, 4); + cmp (v, immm, w); +=20 + /* 1110 0dst CMP.B:S #IMM8,dest */ +=20 + imm =3D IMM(0); + dc =3D decode_dest3 (dst, 0); + v =3D get_src (dc); + cmp (v, imm, 0); +=20 + /* 1100 000w srcx dest CMP.size:G src,dest */ +=20 + BINARY_UOP; + cmp(b, a, w); +=20 + /* 0011 1d sr CMP.B:S src,R0L/R0H */ +=20 + sc =3D decode_src2 (sr, 0, d); + dc =3D decode_dest1 (d, 0); + a =3D get_src (sc); + b =3D get_src (dc); + cmp (b, a, 0); +=20 + /* 0111 110w 1110 i1c s DADC,DADD,DSBB,DSUB */ +=20 + /* w =3D width, i =3D immediate, c =3D carry, s =3D subtract */ +=20 + int src =3D i ? IMM(w) : get_reg (w ? r1 : r0h); + int dest =3D get_reg (w ? r0 : r0l); + int res; +=20 + src =3D bcd2int(src, w); + dest =3D bcd2int(dest, w); +=20 + tprintf("decimal: %d %s %d", dest, s?"-":"+", src); + if (c) + tprintf(" c=3D%d", carry); +=20 + if (!s) + { + res =3D dest + src; + if (c) + res +=3D carry; + c =3D res > (w ? 9999 : 99); + } + else + { + res =3D dest - src; + if (c) + res -=3D (1-carry); + c =3D res >=3D 0; + if (res < 0) + res +=3D w ? 10000 : 100; + } +=20 + res =3D int2bcd (res, w); + tprintf(" =3D %x\n", res); +=20 + set_szc (res, w+1, c); +=20 + put_reg (w ? r0 : r0l, res); +=20 + /* 1010 1dst DEC.B dest */ +=20 + dc =3D decode_dest3 (dst, 0); + v =3D get_src (dc); + tprintf("%x -- =3D %x\n", v, v-1); + v --; + set_sz (v, 1); + put_dest (dc, v); +=20 + /* 1111 d010 DEC.W dest */ +=20 + v =3D get_reg (d ? a1 : a0); + tprintf("%x -- =3D %x\n", v, v-1); + v --; + set_sz (v, 2); + put_reg (d ? a1 : a0, v); +=20 + /* 0111 110w 1110 0001 DIV.size #IMM */ +=20 + div_op (-1, 0, 0, w); +=20 + /* 0111 011w 1101 srcx DIV.size src */ +=20 + div_op (srcx, 0, 0, w); +=20 + /* 0111 110w 1110 0000 DIVU.size #IMM */ +=20 + div_op (-1, 1, 0, w); +=20 + /* 0111 011w 1100 srcx DIVU.size src */ +=20 + div_op (srcx, 1, 0, w); +=20 + /* 0111 110w 1110 0011 DIVX.size #IMM */ +=20 + div_op (-1, 0, 1, w); +=20 + /* 0111 011w 1001 srcx DIVX.size src */ +=20 + div_op (srcx, 0, 1, w); +=20 + /* 0111 1100 1111 0010 ENTER #IMM8 */ +=20 + imm =3D 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); +=20 + /* 0111 1101 1111 0010 EXITD */ +=20 + 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); +=20 + /* 0111 1100 0110 dest EXTS.B dest */ +=20 + dc =3D decode_srcdest4 (dest, 0); + v =3D sign_ext (get_src (dc), 8); + dc =3D widen_sd (dc); + put_dest (dc, v); + set_sz (v, 1); +=20 + /* 0111 1100 1111 0011 EXTS.W R0 */ +=20 + v =3D sign_ext (get_reg (r0), 16); + put_reg (r2r0, v); + set_sz (v, 2); +=20 + /* 1110 1011 0flg 0101 FCLR dest */ +=20 + set_flags (1 << flg, 0); +=20 + /* 1110 1011 0flg 0100 FSET dest */ +=20 + set_flags (1 << flg, 1 << flg); +=20 + /* 1010 0dst INC.B dest */ +=20 + dc =3D decode_dest3 (dst, 0); + v =3D get_src (dc); + tprintf("%x ++ =3D %x\n", v, v+1); + v ++; + set_sz (v, 1); + put_dest (dc, v); +=20 + /* 1011 d010 INC.W dest */ +=20 + v =3D get_reg (d ? a1 : a0); + tprintf("%x ++ =3D %x\n", v, v+1); + v ++; + set_sz (v, 2); + put_reg (d ? a1 : a0, v); +=20 + /* 1110 1011 11vector INT #imm */ +=20 + trigger_based_interrupt (vector); +=20 + /* 1111 0110 INTO */ +=20 + if (FLAG_O) + trigger_fixed_interrupt (0xffe0); +=20 + /* 0110 1cnd Jcnd label */ +=20 + v =3D sign_ext (IMM(0), 8); + if (condition_true (cnd)) + put_reg (pc, orig_pc + 1 + v); +=20 + /* 0111 1101 1100 cond Jcnd label */ +=20 + v =3D sign_ext (IMM(0), 8); + if (condition_true (cond)) + put_reg (pc, orig_pc + 2 + v); +=20 + /* 0110 0dsp JMP.S label */ +=20 + put_reg (pc, orig_pc + 2 + dsp); +=20 + /* 1111 1110 JMP.B label */ +=20 + imm =3D sign_ext (IMM(0), 8); + if (imm =3D=3D -1) + { + if (verbose) + printf("[jmp-to-self detected as exit]\n"); + return M32C_MAKE_HIT_BREAK (); + } + put_reg (pc, orig_pc + 1 + imm); +=20 + /* 1111 0100 JMP.W label */ +=20 + imm =3D sign_ext (IMM(1), 16); + put_reg (pc, orig_pc + 1 + imm); +=20 + /* 1111 1100 JMP.A label */ +=20=20=20 + imm =3D IMM(2); + put_reg (pc, imm); +=20 + /* 0111 1101 0010 srcx JMPI.W src */ +=20 + sc =3D decode_jumpdest (srcx, 1); + a =3D get_src (sc); + a =3D sign_ext (a, 16); + put_reg (pc, orig_pc + a); +=20 + /* 0111 1101 0000 srcx JMPI.A src */ +=20 + sc =3D decode_jumpdest (srcx, 0); + a =3D get_src (sc); + put_reg (pc, a); +=20 + /* 1110 1110 JMPS #IMM8 */ +=20 + M16C_ONLY(); +=20 + imm =3D IMM(0); + a =3D 0xf0000 + mem_get_hi (0xffffe - imm * 2); + put_reg (pc, a); +=20 + /* 1111 0101 JSR.W label */ +=20 + imm =3D 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); +=20 + /* 1111 1101 JSR.A label */ +=20 + imm =3D IMM(2); + put_reg (sp, get_reg (sp) - 3); + mem_put_psi (get_reg (sp), get_reg (pc)); + put_reg (pc, imm); +=20 + /* 0111 1101 0011 srcx JSRI.W src */ +=20 + sc =3D decode_jumpdest (srcx, 1); + a =3D get_src (sc); + a =3D sign_ext (a, 16); +=20 + put_reg (sp, get_reg (sp) - 3); + mem_put_psi (get_reg (sp), get_reg (pc)); + put_reg (pc, orig_pc + a); +=20 + /* 0111 1101 0001 srcx JSRI.A src */ +=20 + sc =3D decode_jumpdest (srcx, 0); + a =3D get_src (sc); +=20 + put_reg (sp, get_reg (sp) - 3); + mem_put_psi (get_reg (sp), get_reg (pc)); + put_reg (pc, a); +=20 + /* 1110 1111 JSRS #IMM8 */ +=20 + M16C_ONLY(); +=20 + imm =3D IMM(0); + a =3D 0xf0000 + mem_get_hi (0xffffe - imm * 2); +=20 + put_reg (sp, get_reg (sp) - 3); + mem_put_psi (get_reg (sp), get_reg (pc)); + put_reg (pc, a); +=20 + /* 1110 1011 0reg 0000 LDC #IMM16,dest */ +=20 + dc =3D decode_cr (reg); + imm =3D IMM(1); + put_dest (dc, imm); +=20 + /* 0111 1010 1reg srcx LDC src,dest */ +=20 + dc =3D decode_cr (reg); + sc =3D decode_srcdest4 (srcx,1); + put_dest (dc, get_src (sc)); +=20 + /* 0111 1100 1111 0000 LDCTX abs16,abs20 */ +=20 + NOTYET(); +=20 + /* 0111 010w 1000 dest LDE.size abs20,dest */ +=20 + dc =3D decode_srcdest4 (dest, w); + imm =3D IMM(2); + if (w) + v =3D mem_get_hi (imm); + else + v =3D mem_get_qi (imm); + put_dest (dc, v); +=20 + /* 0111 010w 1001 dest LDE.size dsp:20[a0], dest */ +=20 + dc =3D decode_srcdest4 (dest, w); + imm =3D IMM(2) + get_reg (a0); + if (w) + v =3D mem_get_hi (imm); + else + v =3D mem_get_qi (imm); + put_dest (dc, v); +=20 + /* 0111 010w 1010 dest LDE.size [a1a0],dest */ +=20=20=20 + dc =3D decode_srcdest4 (dest, w); + imm =3D get_reg (a1a0); + if (w) + v =3D mem_get_hi (imm); + else + v =3D mem_get_qi (imm); + put_dest (dc, v); +=20 + /* 0111 1101 1010 0imm LDIPL #IMM */ +=20 + set_flags (0x700, imm*0x100); +=20 + /* 0111 010w 1100 dest MOV.size:G #IMM,dest */ +=20 + UNARY_UOP; + imm =3D IMM(w); + v =3D imm; + tprintf("%x =3D %x\n", v, v); + set_sz(v, w+1); + put_dest (dc, v); +=20 + /* 1101 100w immm dest MOV.size:Q #IMM,dest */ +=20 + UNARY_SOP; + v =3D sign_ext (immm, 4); + tprintf ("%x =3D %x\n", v, v); + set_sz (v, w+1); + put_dest (dc, v); +=20 + /* 1100 0dst MOV.B:S #IMM8,dest */ +=20 + imm =3D IMM(0); + dc =3D decode_dest3 (dst, 0); + v =3D imm; + tprintf("%x =3D %x\n", v, v); + set_sz (v, 1); + put_dest (dc, v); +=20 + /* 1w10 d010 MOV.size:S #IMM,dest */ +=20 + /* Note that for w, 0=3DW and 1=3DB unlike the usual meaning. */ + v =3D IMM(1-w); + tprintf("%x =3D %x\n", v, v); + set_sz (v, 2-w); + put_reg (d ? a1 : a0, v); +=20 + /* 1011 0dst MOV.B:Z #0,dest */ +=20 + dc =3D decode_dest3 (dst, 0); + v =3D 0; + set_sz (v, 1); + put_dest (dc, v); +=20 + /* 0111 001w srcx dest MOV.size:G src,dest */ +=20 + sc =3D decode_srcdest4 (srcx, w); + dc =3D decode_srcdest4 (dest, w); + v =3D get_src (sc); + set_sz (v, w+1); + put_dest (dc, v); +=20 + /* 0011 0d sr MOV.B:S src,dest */ +=20 + sc =3D decode_src2 (sr, 0, d); + v =3D get_src (sc); + set_sz (v, 1); + put_reg (d ? a1 : a0, v); +=20 + /* 0000 0s ds MOV.B:S R0L/R0H,dest */ +=20 + if (ds =3D=3D 0) + UNSUPPORTED(); + dc =3D decode_src2 (ds, 0, s); + v =3D get_reg (s ? r0h : r0l); + set_sz (v, 1); + put_dest (dc, v); +=20 + /* 0000 1d sr MOV.B:S src,R0L/R0H */ +=20 + sc =3D decode_src2 (sr, 0, d); + v =3D get_src (sc); + set_sz (v, 1); + put_reg (d ? r0h : r0l, v); +=20 + /* 0111 010w 1011 dest MOV.size:G dsp:8[SP], dest */ +=20 + dc =3D decode_srcdest4 (dest, w); + imm =3D IMM(0); + a =3D get_reg (sp) + sign_ext (imm, 8); + a &=3D addr_mask; + if (w) + v =3D mem_get_hi (a); + else + v =3D mem_get_qi (a); + set_sz (v, w+1); + put_dest (dc, v); +=20 + /* 0111 010w 0011 srcx MOV.size:G src, disp8[SP] */ +=20 + sc =3D decode_srcdest4 (srcx, w); + imm =3D IMM(0); + a =3D get_reg (sp) + sign_ext (imm, 8); + a &=3D addr_mask; + v =3D get_src (sc); + if (w) + mem_put_hi (a, v); + else + mem_put_qi (a, v); + set_sz (v, w+1); +=20 + /* 1110 1011 0reg 1src MOVA src,dest */ +=20 + static reg_id map[] =3D { r0, r1, r2, r3, a0, a1, 0, 0 }; + sc =3D decode_srcdest4 (8 + src, 0); + put_reg (map[reg], sc.u.addr); +=20 + /* 0111 1100 10hl dest MOVdir R0L,dest */ +=20 + if (dest =3D=3D 0 || dest =3D=3D 4 || dest =3D=3D 5) + UNSUPPORTED(); + dc =3D decode_srcdest4 (dest, 0); + a =3D get_src (dc); + b =3D get_reg (r0l); + switch (hl) + { + case 0: a =3D (a & 0xf0) | (b & 0x0f); break; + case 1: a =3D (a & 0xf0) | ((b>>4) & 0x0f); break; + case 2: a =3D (a & 0x0f) | ((b & 0x0f)<<4); break; + case 3: a =3D (a & 0x0f) | (b & 0xf0); break; + } + put_dest (dc, a); +=20 + /* 0111 1100 00hl srcx MOVdir src,R0L */ +=20 + if (srcx =3D=3D 0 || srcx =3D=3D 4 || srcx =3D=3D 5) + UNSUPPORTED(); + sc =3D decode_srcdest4 (srcx, 0); + a =3D get_reg (r0l); + b =3D get_src (sc); + switch (hl) + { + case 0: a =3D (a & 0xf0) | (b & 0x0f); break; + case 1: a =3D (a & 0xf0) | ((b>>4) & 0x0f); break; + case 2: a =3D (a & 0x0f) | ((b & 0x0f)<<4); break; + case 3: a =3D (a & 0x0f) | (b & 0xf0); break; + } + put_reg (r0l, a); +=20 + /* 0111 110w 0101 dest MUL.size #IMM,dest */ +=20 + UNARY_SOP; + imm =3D sign_ext (IMM(w), w?16:8); + tprintf("%d * %d =3D %d\n", v, imm, v*imm); + v *=3D imm; + dc =3D widen_sd (dc); + put_dest (dc, v); +=20 + /* 0111 100w srcx dest MUL.size src,dest */ +=20 + BINARY_SOP; + v =3D a * b; + tprintf("%d * %d =3D %d\n", a, b, v); + dc =3D widen_sd (dc); + put_dest (dc, v); +=20 + /* 0111 110w 0100 dest MULU.size #IMM,dest */ +=20 + UNARY_UOP; + imm =3D IMM(w); + tprintf("%u * %u =3D %u\n", v, imm, v*imm); + v *=3D imm; + dc =3D widen_sd (dc); + put_dest (dc, v); +=20 + /* 0111 000w srcx dest MULU.size src,dest */ +=20 + BINARY_UOP; + v =3D a * b; + tprintf("%u * %u =3D %u\n", a, b, v); + dc =3D widen_sd (dc); + put_dest (dc, v); +=20 + /* 0111 010w 0101 dest NEG.size dest */ +=20 + UNARY_SOP; + tprintf("%d * -1 =3D %d\n", v, -v); + v =3D -v; + set_oszc (v, w+1, v =3D=3D 0); + put_dest (dc, v); +=20 + /* 0000 0100 NOP */ +=20 + tprintf("nop\n"); +=20 + /* 0111 010w 0111 dest NOT.size:G */ +=20 + UNARY_UOP; + tprintf("~ %x =3D %x\n", v, ~v); + v =3D ~v; + set_sz (v, w+1); + put_dest (dc, v); +=20 + /* 1011 1dst NOT.B:S dest */ +=20 + dc =3D decode_dest3 (dst, 0); + v =3D get_src (dc); + tprintf("~ %x =3D %x\n", v, ~v); + v =3D ~v; + set_sz (v, 1); + put_dest (dc, v); +=20 + /* 0111 011w 0011 dest OR.size:G #IMM,dest */ +=20 + UNARY_UOP; + imm =3D IMM(w); + tprintf ("%x | %x =3D %x\n", v, imm, v | imm); + v |=3D imm; + set_sz (v, w+1); + put_dest (dc, v); +=20 + /* 1001 1dst OR.B:S #IMM8,dest */ +=20 + imm =3D IMM(0); + dc =3D decode_dest3 (dst, 0); + v =3D get_src (dc); + tprintf("%x | %x =3D %x\n", v, imm, v|imm); + v |=3D imm; + set_sz (v, 1); + put_dest (dc, v); +=20 + /* 1001 100w srcx dest OR.size:G src,dest */ +=20 + BINARY_UOP; + tprintf ("%x | %x =3D %x\n", a, b, a | b); + v =3D a | b; + set_sz (v, w+1); + put_dest (dc, v); +=20 + /* 0001 1d sr OR.B:S src,R0L/R0H */ +=20 + sc =3D decode_src2 (sr, 0, d); + dc =3D decode_dest1 (d, 0); + a =3D get_src (sc); + b =3D get_src (dc); + v =3D a | b; + tprintf("%x | %x =3D %x\n", a, b, v); + set_sz (v, 1); + put_dest (dc, v); +=20 + /* 0111 010w 1101 dest POP.size:G dest */ +=20 + dc =3D decode_srcdest4 (dest, w); + if (w) + { + v =3D mem_get_hi (get_reg (sp)); + put_reg (sp, get_reg (sp) + 2); + tprintf("pophi: %x\n", v); + } + else + { + v =3D mem_get_qi (get_reg (sp)); + put_reg (sp, get_reg (sp) + 1); + tprintf("popqi: %x\n", v); + } + put_dest (dc, v); +=20 + /* 1001 d010 POP.B:S dest */ +=20 + v =3D mem_get_qi (get_reg (sp)); + put_reg (d ? r0h : r0l, v); + put_reg (sp, get_reg (sp) + 1); + tprintf("popqi: %x\n", v); +=20 + /* 1101 d010 POP.W:S dest */ +=20 + v =3D mem_get_hi (get_reg (sp)); + put_reg (d ? a1 : a0, v); + put_reg (sp, get_reg (sp) + 2); + tprintf("pophi: %x\n", v); +=20 + /* 1110 1011 0reg 0011 POPC dest */ +=20 + dc =3D decode_cr (reg); + v =3D mem_get_hi (get_reg (sp)); + put_dest (dc, v); + put_reg (sp, get_reg (sp) + 2); + tprintf("popc: %x\n", v); +=20 + /* 1110 1101 POPM dest */ +=20 + static int map[] =3D { r0, r1, r2, r3, a0, a1, sb, fb }; + imm =3D IMM(0); + tprintf("popm: %x\n", imm); + for (a=3D0; a<8; a++) + if (imm & (1<=3D 0); +=20 + /* 1011 100w srcx dest SBB.size src,dest */ +=20 + sc =3D decode_srcdest4(srcx, w); + dc =3D decode_srcdest4(dest, w); + b =3D get_src (sc); + MATH_OP (dc, b, !carry, -, >=3D 0); +=20 + /* 1111 000w immm dest SHA.size #IMM, dest */ +=20 + dc =3D decode_srcdest4(dest, w); + shift_op (dc, 1, IMM4()); +=20 + /* 0111 010w 1111 dest SHA.size R1H,dest */ +=20 + dc =3D decode_srcdest4(dest, w); + a =3D sign_ext (get_reg (r1h), 8); + shift_op (dc, 1, a); +=20 + /* 1110 1011 101d immm SHA.L #IMM, dest */ +=20 + dc =3D reg_sd (d ? r3r1 : r2r0); + shift_op (dc, 1, IMM4()); +=20 + /* 1110 1011 001d 0001 SHA.L R1H,dest */ +=20 + dc =3D reg_sd (d ? r3r1 : r2r0); + a =3D sign_ext (get_reg (r1h), 8); + shift_op (dc, 1, a); +=20 + /* 1110 100w immm dest SHL.size #IMM, dest */ +=20 + dc =3D decode_srcdest4(dest, w); + shift_op (dc, 0, IMM4()); +=20 + /* 0111 010w 1110 dest SHL.size R1H,dest */ +=20 + dc =3D decode_srcdest4(dest, w); + a =3D sign_ext (get_reg (r1h), 8); + shift_op (dc, 0, a); +=20 + /* 1110 1011 100d immm SHL.L #IMM,dest */ +=20 + dc =3D reg_sd (d ? r3r1 : r2r0); + shift_op (dc, 0, IMM4()); +=20 + /* 1110 1011 000d 0001 SHL.L R1H,dest */ +=20 + dc =3D reg_sd (d ? r3r1 : r2r0); + a =3D sign_ext (get_reg (r1h), 8); + shift_op (dc, 0, a); +=20 + /* 0111 110w 1110 100b SMOVB.size */ +=20 + int count =3D get_reg (r3); + int s1 =3D get_reg (a0) + (get_reg (r1h) << 16); + int s2 =3D get_reg (a1); + int inc =3D (w ? 2 : 1) * (b ? -1 : 1); +=20 + while (count) + { + if (w) + { + v =3D mem_get_hi (s1); + mem_put_hi (s2, v); + } + else + { + v =3D mem_get_qi (s1); + mem_put_qi (s2, v); + } + s1 +=3D inc; + s2 +=3D inc; + count --; + } + put_reg (r3, count); + put_reg (a0, s1 & 0xffff); + put_reg (a1, s2); + put_reg (r1h, s1 >> 16); +=20 + /* 0111 110w 1110 1010 SSTR.size */ +=20 + int count =3D get_reg (r3); + int s1 =3D get_reg (a1); + v =3D get_reg (w ? r0 : r0h); +=20 + while (count) + { + if (w) + { + mem_put_hi (s1, v); + s1 +=3D 2; + } + else + { + mem_put_qi (s1, v); + s1 +=3D 1; + } + count --; + } + put_reg (r3, count); + put_reg (a1, s1); +=20 + /* 0111 1011 1src dest STC src,dest */ +=20 + dc =3D decode_srcdest4 (dest, 1); + sc =3D decode_cr (src); + put_dest (dc, get_src(sc)); +=20 + /* 0111 1100 1100 dest STC PC,dest */ +=20 + dc =3D decode_srcdest4 (dest, 1); + dc.bytes =3D 3; + put_dest (dc, orig_pc); +=20 + /* 0111 1101 1111 0000 STCTX abs16,abs20 */ +=20 + NOTYET(); +=20 + /* 0111 010w 0000 srcx STE.size src,abs20 */ +=20 + sc =3D decode_srcdest4 (srcx, w); + a =3D IMM(2); + v =3D get_src (sc); + if (w) + mem_put_hi (a, v); + else + mem_put_qi (a, v); + if (srcx =3D=3D 4 || srcx =3D=3D 5) + { + v =3D get_reg (sc.u.reg); + set_sz (v, 2); + } + else + set_sz (v, w+1); +=20=20=20=20=20 + /* 0111 010w 0001 srcx STE.size src,disp20[a0] */ +=20 + sc =3D decode_srcdest4 (srcx, w); + a =3D get_reg(a0) + IMM(2); + v =3D get_src (sc); + if (w) + mem_put_hi (a, v); + else + mem_put_qi (a, v); + if (srcx =3D=3D 4 || srcx =3D=3D 5) + { + v =3D get_reg (sc.u.reg); + set_sz (v, 2); + } + else + set_sz (v, w+1); +=20 + /* 0111 010w 0010 srcx STE.size src,[a1a0] */ +=20 + sc =3D decode_srcdest4 (srcx, w); + a =3D get_reg(a1a0); + v =3D get_src (sc); + if (w) + mem_put_hi (a, v); + else + mem_put_qi (a, v); + if (srcx =3D=3D 4 || srcx =3D=3D 5) + { + v =3D get_reg (sc.u.reg); + set_sz (v, 2); + } + else + set_sz (v, w+1); +=20 + /* 1101 0dst STNZ #IMM8,dest */ +=20 + imm =3D IMM(0); + dc =3D decode_dest3(dst, 0); + if (!FLAG_Z) + put_dest (dc, imm); +=20 + /* 1100 1dst STZ #IMM8,dest */ +=20 + imm =3D IMM(0); + dc =3D decode_dest3(dst, 0); + if (FLAG_Z) + put_dest (dc, imm); +=20 + /* 1101 1dst STZX #IMM81,#IMM82,dest */ +=20 + a =3D IMM(0); + dc =3D decode_dest3(dst, 0); + b =3D IMM(0); + if (FLAG_Z) + put_dest (dc, a); + else + put_dest (dc, b); +=20 + /* 0111 011w 0101 dest SUB.size:G #IMM,dest */ +=20 + dc =3D decode_srcdest4 (dest, w); + imm =3D IMM(w); + MATH_OP (dc, imm, 0, -, >=3D 0); +=20 + /* 1000 1dst SUB.B:S #IMM8,dest */ +=20 + imm =3D IMM(0); + dc =3D decode_dest3 (dst, 0); + MATH_OP (dc, imm, 0, -, >=3D 0); +=20 + /* 1010 100w srcx dest SUB.size:G src,dest */ +=20 + sc =3D decode_srcdest4(srcx, w); + dc =3D decode_srcdest4(dest, w); + b =3D get_src (sc); + MATH_OP (dc, b, 0, -, > 0); +=20 + /* 0010 1d sr SUB.B:S src,R0L/R0H */ +=20 + sc =3D decode_src2 (sr, 0, d); + dc =3D decode_dest1 (d, 0); + b =3D get_src (sc); + MATH_OP (dc, b, 0, -, > 0); +=20 + /* 0111 011w 0000 dest TST.size #IMM, dest */ +=20 + UNARY_UOP; + imm =3D IMM(w); + tprintf ("%x & %x =3D %x\n", v, imm, v & imm); + v &=3D imm; + set_sz (v, w+1); +=20 + /* 1000 000w srcx dest TST.size src,dest */ +=20 + BINARY_UOP; + tprintf ("%x & %x =3D %x\n", a, b, a & b); + v =3D a & b; + set_sz (v, w+1); +=20 + /* 1111 1111 UND */ +=20 + trigger_fixed_interrupt (0xffdc); +=20 + /* 0111 1101 1111 0011 WAIT */ +=20 + tprintf("waiting...\n"); +=20 + /* 0111 101w 00sr dest XCHG.size src,dest */ +=20 + sc =3D decode_srcdest4 (sr, w); + dc =3D decode_srcdest4 (dest, w); + a =3D get_src (sc); + b =3D get_src (dc); + put_dest (dc, a); + put_dest (sc, b); +=20 + /* 0111 011w 0001 dest XOR.size #IMM,dest */ +=20 + UNARY_UOP; + imm =3D IMM(w); + tprintf ("%x ^ %x =3D %x\n", v, imm, v ^ imm); + v ^=3D imm; + set_sz (v, w+1); + put_dest (dc, v); +=20 + /* 1000 100w srcx dest XOR.size src,dest */ +=20 + BINARY_UOP; + tprintf ("%x ^ %x =3D %x\n", a, b, a ^ b); + v =3D a ^ b; + set_sz (v, w+1); + put_dest (dc, v); +=20=20=20 + /* OP */ + /* */ +=20 + return step_result; + } Index: sim/m32c/reg.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 + #include + #include +=20 + #include "cpu.h" +=20 + int verbose =3D 0; + int trace =3D 0; + int enable_counting =3D 0; +=20 + regs_type regs; + int addr_mask =3D 0xffff; + int membus_mask =3D 0xfffff; + int m32c_cpu =3D 0; + int step_result; + unsigned int heapbottom =3D 0; + unsigned int heaptop =3D 0; +=20 + char *reg_names[] =3D { + "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" + }; +=20 + int reg_bytes[] =3D { + 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 + }; +=20 +=20 + unsigned int b2mask[] =3D { 0, 0xff, 0xffff, 0xffffff, 0xffffffff }; + unsigned int b2signbit[] =3D { 0, (1<<7), (1<<15), (1<<24), (1<<31) }; + int b2maxsigned[] =3D { 0, 0x7f, 0x7fff, 0x7fffff, 0x7fffffff }; + int b2minsigned[] =3D { 0, -128, -32768, -8388608, -2147483647-1 }; +=20 + static regs_type oldregs; +=20 + void + init_regs (void) + { + memset (®s, 0, sizeof (regs)); + memset (&oldregs, 0, sizeof (oldregs)); + } +=20 + void + set_pointer_width (int bytes) + { + if (bytes =3D=3D 2) + { + addr_mask =3D 0xffff; + membus_mask =3D 0x000fffff; + reg_bytes[a0] =3D reg_bytes[a1] =3D reg_bytes[sb] =3D reg_bytes[fb]= =3D + reg_bytes[sp] =3D reg_bytes[usp] =3D reg_bytes[isp] =3D 2; + } + else + { + addr_mask =3D 0xffffff; + membus_mask =3D 0x00ffffff; + reg_bytes[a0] =3D reg_bytes[a1] =3D reg_bytes[sb] =3D reg_bytes[fb]= =3D + reg_bytes[sp] =3D reg_bytes[usp] =3D reg_bytes[isp] =3D 3; + } + } +=20 + void + m32c_set_cpu (int cpu) + { + switch (cpu) + { + case CPU_R8C: + case CPU_M16C: + set_pointer_width (2); + decode_opcode =3D decode_r8c; + break; + case CPU_M32CM: + case CPU_M32C: + set_pointer_width (3); + decode_opcode =3D decode_m32c; + break; + default: + abort(); + } + m32c_cpu =3D cpu; + } +=20 + static unsigned int + get_reg_i (reg_id id) + { + reg_bank_type *b =3D regs.r + (FLAG_B ? 1 : 0); +=20 + 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; +=20 + 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); +=20 + case sb: + return b->r_sb & addr_mask; + case fb: + return b->r_fb & addr_mask; +=20 + case intb: + return regs.r_intbh * 65536 + regs.r_intbl; + case intbl: + return regs.r_intbl; + case intbh: + return regs.r_intbh; +=20 + case sp: + return ((regs.r_flags & FLAGBIT_U) ? regs.r_usp : regs.r_isp) & add= r_mask; + case usp: + return regs.r_usp & addr_mask; + case isp: + return regs.r_isp & addr_mask; +=20 + case pc: + return regs.r_pc & membus_mask; + case flags: + return regs.r_flags; + default: + abort(); + } + } +=20 + unsigned int + get_reg (reg_id id) + { + unsigned int rv =3D get_reg_i (id); + if (trace > ((id !=3D pc && id !=3D fb && id !=3D sp) ? 0 : 1)) + printf("get_reg (%s) =3D %0*x\n", reg_names[id], reg_bytes[id]*2, rv); + return rv; + } +=20 + DI + get_reg_ll (reg_id id) + { + reg_bank_type *b =3D regs.r + (FLAG_B ? 1 : 0); +=20 + 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); + } + } +=20 + static int highest_sp=3D0, lowest_sp=3D0xffffff; +=20 + 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, highes= t_sp - lowest_sp); + } +=20 + void + put_reg (reg_id id, unsigned int v) + { + if (trace > ((id !=3D pc) ? 0 : 1)) + printf("put_reg (%s) =3D %0*x\n", reg_names[id], reg_bytes[id]*2, v); +=20=20=20=20=20 + reg_bank_type *b =3D regs.r + (FLAG_B ? 1 : 0); + switch (id) + { + case r0: + b->r_r0 =3D v; + break; + case r0h: + b->r_r0 =3D (b->r_r0 & 0xff) | (v << 8); + break; + case r0l: + b->r_r0 =3D (b->r_r0 & 0xff00) | (v & 0xff); + break; + case r1: + b->r_r1 =3D v; + break; + case r1h: + b->r_r1 =3D (b->r_r1 & 0xff) | (v << 8); + break; + case r1l: + b->r_r1 =3D (b->r_r1 & 0xff00) | (v & 0xff); + break; + case r2: + b->r_r2 =3D v; + break; + case r2r0: + b->r_r0 =3D v & 0xffff; + b->r_r2 =3D v >> 16; + break; + case r3: + b->r_r3 =3D v; + break; + case r3r1: + b->r_r1 =3D v & 0xffff; + b->r_r3 =3D v >> 16; + break; +=20 + case a0: + b->r_a0 =3D v & addr_mask; + break; + case a1: + b->r_a1 =3D v & addr_mask; + break; + case a1a0: + b->r_a0 =3D v & 0xffff; + b->r_a1 =3D v >> 16; + break; +=20 + case sb: + b->r_sb =3D v & addr_mask; + break; + case fb: + b->r_fb =3D v & addr_mask; + break; +=20 + case intb: + regs.r_intbl =3D v & 0xffff; + regs.r_intbh =3D v >> 16; + break; + case intbl: + regs.r_intbl =3D v & 0xffff; + break; + case intbh: + regs.r_intbh =3D v & 0xff; + break; +=20 + case sp: + { + SI *spp; + if (regs.r_flags & FLAGBIT_U) + spp =3D ®s.r_usp; + else + spp =3D ®s.r_isp; + *spp =3D v & addr_mask; + if (*spp < heaptop) + { + printf("collision: pc %08lx heap %08x stack %08lx\n", regs.r_pc, hea= ptop, *spp); + exit(1); + } + if (*spp < lowest_sp) + lowest_sp =3D *spp; + if (*spp > highest_sp) + highest_sp =3D *spp; + break; + } + case usp: + regs.r_usp =3D v & addr_mask; + break; + case isp: + regs.r_isp =3D v & addr_mask; + break; +=20 + case pc: + regs.r_pc =3D v & membus_mask; + break; + case flags: + regs.r_flags =3D v; + break; + default: + abort(); + } + } +=20 + int + condition_true (int cond_id) + { + int f; + if (A16) + { + static const char *cond_name[] =3D { + "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 =3D FLAG_C; break; /* GEU/C */ + case 1: f =3D FLAG_C & ! FLAG_Z; break; /* GTU */ + case 2: f =3D FLAG_Z; break; /* EQ/Z*/ + case 3: f =3D FLAG_S; break; /* N */ + case 4: f =3D ! FLAG_C; break; /* LTU/NC */ + case 5: f =3D ! (FLAG_C & !FLAG_Z); break; /* LEU */ + case 6: f =3D ! FLAG_Z; break; /* NE/NZ */ + case 7: f =3D ! FLAG_S; break; /* PZ */ +=20 + case 8: f =3D (FLAG_S ^ FLAG_O) | FLAG_Z; break; /* LE */ + case 9: f =3D FLAG_O; break; /* O */ + case 10: f =3D !(FLAG_S ^ FLAG_O); break; /* GE */ + case 12: f =3D !((FLAG_S ^ FLAG_O) | FLAG_Z); break; /* GT */ + case 13: f =3D ! FLAG_O; break; /* NO */ + case 14: f =3D FLAG_S ^ FLAG_O; break; /* LT */ +=20 + default: + f =3D 0; + break; + } + if (trace) + printf("cond[%d] %s =3D %s\n", cond_id, cond_name[cond_id&15], f?"true":= "false"); + } + else + { + static const char *cond_name[] =3D { + "!C", "LEU", "!Z", "PZ", + "!O", "GT", "GE", "?", + "C", "GTU", "Z", "N", + "O", "LE", "LT", "!?"}; + switch (cond_id) + { + case 0: f =3D ! FLAG_C; break; /* LTU/NC */ + case 1: f =3D ! (FLAG_C & !FLAG_Z); break; /* LEU */ + case 2: f =3D ! FLAG_Z; break; /* NE/NZ */ + case 3: f =3D ! FLAG_S; break; /* PZ */ +=20 + case 4: f =3D ! FLAG_O; break; /* NO */ + case 5: f =3D !((FLAG_S ^ FLAG_O) | FLAG_Z); break; /* GT */ + case 6: f =3D !(FLAG_S ^ FLAG_O); break; /* GE */ +=20 + case 8: f =3D FLAG_C; break; /* GEU/C */ + case 9: f =3D FLAG_C & ! FLAG_Z; break; /* GTU */ + case 10: f =3D FLAG_Z; break; /* EQ/Z*/ + case 11: f =3D FLAG_S; break; /* N */ +=20 + case 12: f =3D FLAG_O; break; /* O */ + case 13: f =3D (FLAG_S ^ FLAG_O) | FLAG_Z; break; /* LE */ + case 14: f =3D FLAG_S ^ FLAG_O; break; /* LT */ +=20 + default: + f =3D 0; + break; + } + if (trace) + printf("cond[%d] %s =3D %s\n", cond_id, cond_name[cond_id&15], f?"true":= "false"); + } + return f; + } +=20 + void + set_flags (int mask, int newbits) + { + int i; + regs.r_flags &=3D ~mask; + regs.r_flags |=3D newbits & mask; + if (trace) + { + printf("flags now \033[32m %d", (regs.r_flags >> (A16 ? 8 : 12))&7); + for (i=3D7; i>=3D0; i--) + if (regs.r_flags & (1< b2maxsigned[b]) + || (value < b2minsigned[b])) + f |=3D FLAGBIT_O; + set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f); + } +=20 + void + set_szc (int value, int b, int c) + { + int mask =3D b2mask[b]; + int f =3D 0; +=20 + if (c) + f |=3D FLAGBIT_C; + if ((value & mask) =3D=3D 0) + f |=3D FLAGBIT_Z; + if (value & b2signbit[b]) + f |=3D FLAGBIT_S; + set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_C, f); + } +=20 + void + set_osz (int value, int b) + { + int mask =3D b2mask[b]; + int f =3D 0; +=20 + if ((value & mask) =3D=3D 0) + f |=3D FLAGBIT_Z; + if (value & b2signbit[b]) + f |=3D FLAGBIT_S; + if (value & ~mask + && (value & ~mask) !=3D ~mask) + f |=3D FLAGBIT_O; + set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O, f); + } +=20 + void + set_sz (int value, int b) + { + int mask =3D b2mask[b]; + int f =3D 0; +=20 + if ((value & mask) =3D=3D 0) + f |=3D FLAGBIT_Z; + if (value & b2signbit[b]) + f |=3D FLAGBIT_S; + set_flags (FLAGBIT_Z | FLAGBIT_S, f); + } +=20 + void + set_zc (int z, int c) + { + set_flags (FLAGBIT_C | FLAGBIT_Z, (c ? FLAGBIT_C : 0) | (z ? FLAGBIT_Z = : 0)); + } +=20 + void + set_c (int c) + { + set_flags (FLAGBIT_C, c ? FLAGBIT_C : 0); + } +=20 + void + put_reg_ll (reg_id id, DI v) + { + reg_bank_type *b =3D regs.r + (FLAG_B ? 1 : 0); +=20 + switch (id) + { + case r3r1r2r0: + b->r_r3 =3D v>>48; + b->r_r1 =3D v>>32; + b->r_r2 =3D v>>16; + b->r_r0 =3D v; + break; + case r3r2r1r0: + b->r_r3 =3D v>>48; + b->r_r2 =3D v>>32; + b->r_r1 =3D v>>16; + b->r_r0 =3D v; + break; + default: + put_reg (id, v); + } + } +=20 + #define TRC(f,n, id) \ + if (oldregs.f !=3D 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 =3D regs.f; \ + } +=20 + 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 + #include + #include + #include + #include + #include + #include /* mmap() is defined in this header */ + #include + #include + #include + extern "C" { + #include "elfload.h" + } +=20 + #define USI unsigned long + #define SI long + #define UHI unsigned short + #define HI short + #define UQI unsigned char + #define QI char +=20 + enum modes_t {qi=3D0, hi=3D1, si=3D2}; + enum op_fetch_t {src_op=3D1, dest_op=3D0}; +=20 + class m32c_cpu_type + { + public: +=20 + // CPU state information. +=20 + // 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=20 + { + int a1a0; + struct hi + { + HI a1; + HI a0; + } hi; + } a1a0; + HI h_sb; + HI h_sp; + HI h_fb; +=20 + union memory + { + QI qi [16 * 1024]; + HI hi [8 * 1024]; + int si [4 * 1024]; + } memory; +=20=20=20 + /* program counter */ + int h_pc; +=20 + /* 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; +=20 + /* program text */ + union text + { + QI *h_qitext; + HI *h_hitext; + } text; +=20 + 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"; + } + } + } +=20 + 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"; + } + } + } +=20=20=20 + // 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; + } + } + } +=20=20=20 +=20 + inline int h_rset (int regno, modes_t mode, int newval) + { + switch (mode) + { + case qi: + switch (regno) + { + case 0: return this->r2r0.qi.r0l =3D newval; + case 1: return this->r2r0.qi.r0h =3D newval; + case 2: return this->r3r1.qi.r1l =3D newval; + case 3: return this->r3r1.qi.r1h =3D newval; + } + case hi: + switch (regno) + { + case 0: return this->r2r0.hi.r0 =3D newval; + case 1: return this->r3r1.hi.r1 =3D newval; + case 2: return this->r2r0.hi.r2 =3D newval; + case 3: return this->r3r1.hi.r3 =3D newval; + } + case si: + switch (regno) + { + case 0: return this->r2r0.r2r0 =3D newval; + case 1: return this->r3r1.r3r1 =3D newval; + } + } + } +=20 + 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 =3D newval; + case 0: return this->a1a0.hi.a0 =3D newval; + } + } +=20 + inline int h_memget (int address, modes_t mode) + { + if (mode =3D=3D qi) + return this->memory.qi[address]; + else if (mode =3D=3D hi) + return this->memory.hi[address / 2]; + else if (mode =3D=3D si) + return this->memory.hi[address / 4]; + } +=20 + inline int h_memset (int address, int newval, modes_t mode) + { + if (mode =3D=3D qi) + return this->memory.qi[address] =3D newval; + else if (mode =3D=3D hi) + return this->memory.hi[address / 2] =3D newval; + else if (mode =3D=3D si) + return this->memory.hi[address / 4] =3D newval; + } +=20 + 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D newval; } + inline void h_pc_inc (int newval) { this->h_pc =3D this->h_pc + newval;= } + inline void h_pc_set (int newval) { this->h_pc =3D newval; } + inline void h_fb_set (int newval) { this->h_fb =3D newval; } + inline QI* h_qitext_get () const { return this->text.h_qitext; } + inline void h_qitext_set (QI* newval) { this->text.h_qitext =3D newval;= } + inline HI* h_hitext_get () const { return this->text.h_hitext; } + inline void h_hitext_set (HI* newval) { this->text.h_hitext =3D newval;= } +=20 + std::string insn_str; + std::string trace_str; + unsigned long long raw_insn; + } m32c_cpu; +=20 + bool disassemble =3D true; +=20 + bool + addhi_cf (HI s1, HI s2) + { + return (UHI)((UHI)s1 + (UHI)s2) + < (UHI)s1; + } +=20 + bool + subhi_cf (HI s1, HI s2) + { + return (UHI)s1 < (UHI)s2; + } +=20 + bool + addhi_of (HI s1, HI s2) + { + return ((((HI)s1 < 0) =3D=3D ((HI)s2 < 0)) + && (((HI)s1 < 0) !=3D (((HI)((HI)s1 + (HI)s2)) < 0))); + } +=20 + bool + subhi_of (HI s1, HI s2) + { + return ((((HI)s1 < 0) =3D=3D ((HI)s2 < 0)) + && (((HI)s1 < 0) !=3D (((HI)((HI)s1 - (HI)s2)) < 0))); + } +=20 +=20 + bool + addqi_cf (QI s1, QI s2) + { + return (UQI)((UQI)s1 + (UQI)s2) + < (UQI)s1; + } +=20 + bool + subqi_cf (QI s1, QI s2) + { + return (UQI)s1 < (UQI)s2; + } +=20 + bool + addqi_of (QI s1, QI s2) + { + return ((((QI)s1 < 0) =3D=3D ((QI)s2 < 0)) + && (((QI)s1 < 0) !=3D (((QI)((QI)s1 + (QI)s2)) < 0))); + } +=20 + bool + subqi_of (QI s1, QI s2) + { + return ((((QI)s1 < 0) =3D=3D ((QI)s2 < 0)) + && (((QI)s1 < 0) !=3D (((QI)((QI)s1 - (QI)s2)) < 0))); + } +=20 +=20 + HI + get_bits (const void *p, int bits, int big_p) + { + const QI *addr =3D (QI*)p; + HI data; + int i; + int bytes; +=20=20 + if (bits % 8 !=3D 0) + abort (); +=20=20 + data =3D 0; + bytes =3D bits / 8; + for (i =3D 0; i < bytes; i++) + { + int index =3D big_p ? i : bytes - i - 1; + data =3D (USI)(data << 8) | (UQI)addr[index]; + } + return data; + } +=20 + std::string int_to_string (HI x) + { + std::ostringstream o; + if (o << "0x" << std::hex << x) + return o.str(); + return "conversion error"; + } +=20 + int + get_src (int src, modes_t mode, bool inc_pc) + { + int offset; + QI *qi_addr; + HI *hi_addr; +=20=20=20 + switch (src) + { + case 0: + if (inc_pc) + m32c_cpu.insn_str =3D m32c_cpu.insn_str + m32c_cpu.h_gregname (0, mode) = + ","; + // m32c_cpu.trace_str =3D m32c_cpu.h_gregname (0, mode) + "=3D" + // + 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 =3D m32c_cpu.insn_str + m32c_cpu.h_gregname (1, mode); + // m32c_cpu.trace_str =3D m32c_cpu.h_gregname (1, mode) + "=3D" + // + 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 =3D m32c_cpu.insn_str + m32c_cpu.h_gregname (2, mode); + // m32c_cpu.trace_str =3D m32c_cpu.h_gregname (2, mode) + "=3D" + // + 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 =3D m32c_cpu.insn_str + m32c_cpu.h_gregname (3, mode); + // m32c_cpu.trace_str =3D m32c_cpu.h_gregname (3, mode) + "=3D" + // + 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 =3D m32c_cpu.insn_str + m32c_cpu.h_aregname (0, mode); + // m32c_cpu.trace_str =3D m32c_cpu.h_aregname (0, mode) + "=3D" + // + 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 =3D m32c_cpu.insn_str + m32c_cpu.h_aregname (1, mode); + // m32c_cpu.trace_str =3D m32c_cpu.h_aregname (1, mode) + "=3D" + // + 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 =3D m32c_cpu.insn_str + "[a0]"; + // m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_ahi_get (0)) + = "=3D" + // + 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 =3D m32c_cpu.insn_str + "[a1],"; + // m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_ahi_get (1)) + = "=3D" + // + 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 =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + offset =3D get_bits (qi_addr, 8, 0); + if (inc_pc) + { + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + + "[a0],"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 8) + offset; + m32c_cpu.h_pc_inc(1); + } + // m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_ahi_get (0) + offset) + // + "=3D" + 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 =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + offset =3D get_bits (qi_addr, 8, 0); + if (inc_pc) + { + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + + "[a1],"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 8) + offset; + m32c_cpu.h_pc_inc(1); + } + // m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_ahi_get (1) + offset) + // + "=3D" + 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 =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + offset =3D get_bits (qi_addr, 8, 0); + if (inc_pc) + { + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + + "[sb],"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 8) + offset; + m32c_cpu.h_pc_inc(1); + } + // m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_sb_get () + offset) + // + "=3D" + 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 =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + offset =3D get_bits (qi_addr, 8, 0); + if (inc_pc) + { + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + + "[fb],"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 8) + offset; + m32c_cpu.h_pc_inc(1); + } + // m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_fb_get () + offset) + // + "=3D" + 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 =3D (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get()); + offset =3D get_bits (hi_addr, 16, 0); + if (inc_pc) + { + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + + "[a0],"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 8) + offset; + m32c_cpu.h_pc_inc(2); + } + // m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_ahi_get (0) + offset) + // + "=3D" + 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 =3D (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get()); + offset =3D get_bits (hi_addr, 16, 0); + if (inc_pc) + { + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + + "[a1],"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 8) + offset; + m32c_cpu.h_pc_inc(2); + } + // m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_ahi_get (1) + offset) + // + "=3D" + 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 =3D (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get()); + offset =3D get_bits (hi_addr, 16, 0); + if (inc_pc) + { + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + + "[sb],"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 8) + offset; + m32c_cpu.h_pc_inc(2); + } + // m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_sb_get () + offset) + // + "=3D" + 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 =3D (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get()); + offset =3D get_bits (hi_addr, 16, 0); + if (inc_pc) + { + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + "= ,"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 16) + offset; + m32c_cpu.h_pc_inc(2); + } + m32c_cpu.trace_str =3D int_to_string (offset) + "=3D" + + int_to_string (m32c_cpu.h_memget (offset, hi)) + " "; + return m32c_cpu.h_memget (offset, hi); + } + } + } +=20 + int + get_imm_src (int src, modes_t mode) + { + UHI offset; + QI *qi_addr; + HI *hi_addr; + int size; +=20=20=20 + switch (mode) + { + case qi: size =3D 8; break; + case hi: size =3D 16; break; + case si: size =3D 32; break; + } +=20=20=20 + switch (src) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + offset =3D get_bits (qi_addr, size, 0); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + = ","; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << size) + offset; + return offset; + case 8: + case 9: + case 10: + case 11: + { + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get() + 1; + offset =3D get_bits (qi_addr, size, 0); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + ","; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << size) + offset; + return offset; + } + case 12: + case 13: + case 14: + case 15: + { + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get() + 2; + offset =3D get_bits (qi_addr, size, 0); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + ","; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << size) + offset; + return offset; + } + } + } +=20 + int + put_dest (int dest, int newval, modes_t mode) + { + int offset; + QI *qi_addr; + HI *hi_addr; + int size; +=20=20=20 + switch (mode) + { + case qi: size =3D 8; break; + case hi: size =3D 16; break; + case si: size =3D 32; break; + } +=20 + switch (dest) + { + case 0: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + m32c_cpu.h_gregname (0, m= ode); + m32c_cpu.trace_str =3D m32c_cpu.trace_str + + m32c_cpu.h_gregname (0, mode) + "=3D" + int_to_string (newval); + return m32c_cpu.h_rset (0, mode, newval); + case 1: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + m32c_cpu.h_gregname (1, m= ode); + m32c_cpu.trace_str =3D m32c_cpu.trace_str + + m32c_cpu.h_gregname (1, mode) + "=3D" + int_to_string (newval); + return m32c_cpu.h_rset (1, mode, newval); + case 2: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + m32c_cpu.h_gregname (2, m= ode); + m32c_cpu.trace_str =3D m32c_cpu.trace_str + + m32c_cpu.h_gregname (2, mode) + "=3D" + int_to_string (newval); + return m32c_cpu.h_rset (2, mode, newval); + case 3: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + m32c_cpu.h_gregname (3, m= ode); + m32c_cpu.trace_str =3D m32c_cpu.trace_str + + m32c_cpu.h_gregname (3, mode) + "=3D" + int_to_string (newval); + return m32c_cpu.h_rset (3, mode, newval); + case 4: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + m32c_cpu.h_aregname (0, m= ode); + m32c_cpu.trace_str =3D m32c_cpu.trace_str + + m32c_cpu.h_aregname (0, mode) + "=3D" + int_to_string (newval); + return m32c_cpu.h_ahi_set (0, newval); + case 5: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + m32c_cpu.h_aregname (1, m= ode); + m32c_cpu.trace_str =3D m32c_cpu.trace_str + + m32c_cpu.h_aregname (1, mode) + "=3D" + int_to_string (newval); + return m32c_cpu.h_ahi_set (1, newval); + case 6: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + "[a0]"; + m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_ahi_get (0)) + "= =3D" + + int_to_string (newval); + return m32c_cpu.h_memset (m32c_cpu.h_ahi_get (0), newval, mode); + case 7: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + "[a1]"; + m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_ahi_get (1)) + "= =3D" + + int_to_string (newval); + return m32c_cpu.h_memset (m32c_cpu.h_ahi_get (1), newval, mode); + case 8: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + offset =3D get_bits (qi_addr, 8, 0); + m32c_cpu.h_pc_inc(1); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + = "[a0]"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 8) + offset; + m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_ahi_get (0) + offs= et) + + "=3D" + int_to_string (newval); + return m32c_cpu.h_memset (m32c_cpu.h_ahi_get (0) + offset, newval, = mode); + case 9: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + offset =3D get_bits (qi_addr, 8, 0); + m32c_cpu.h_pc_inc(1); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + = "[a1]"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 8) + offset; + m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_ahi_get (1) + offs= et) + + "=3D" + int_to_string (newval); + return m32c_cpu.h_memset (m32c_cpu.h_ahi_get (1) + offset, newval, = mode); + case 10: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + offset =3D get_bits (qi_addr, 8, 0); + m32c_cpu.h_pc_inc(1); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + = "[sb]"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 8) + offset; + m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_sb_get () + offset) + + "=3D" + int_to_string (newval); + return m32c_cpu.h_memset (m32c_cpu.h_sb_get () + offset, newval, mo= de); + case 11: + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + offset =3D get_bits (qi_addr, 8, 0); + m32c_cpu.h_pc_inc(1); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + = "[fb]"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 8) + offset; + m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_fb_get () + offset) + + "=3D" + int_to_string (newval); + return m32c_cpu.h_memset (m32c_cpu.h_fb_get () + offset, newval, mo= de); + case 12: + hi_addr =3D (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get()); + offset =3D get_bits (hi_addr, 16, 0); + m32c_cpu.h_pc_inc(2); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + = "[a0]"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 16) + offset; + m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_ahi_get (0) + offs= et) + + "=3D" + int_to_string (newval); + return m32c_cpu.h_memset (m32c_cpu.h_ahi_get (0) + offset, newval, = mode); + case 13: + hi_addr =3D (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get()); + offset =3D get_bits (hi_addr, 16, 0); + m32c_cpu.h_pc_inc(2); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + = "[a1]"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 16) + offset; + m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_ahi_get (1) + offs= et) + + "=3D" + int_to_string (newval); + return m32c_cpu.h_memset (m32c_cpu.h_ahi_get (1) + offset, newval, = mode); + case 14: + hi_addr =3D (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get()); + offset =3D get_bits (hi_addr, 16, 0); + m32c_cpu.h_pc_inc(2); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset) + = "[sb]"; + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 16) + offset; + m32c_cpu.trace_str =3D int_to_string (m32c_cpu.h_sb_get () + offset) + + "=3D" + int_to_string (newval); + return m32c_cpu.h_memset (m32c_cpu.h_sb_get () + offset, newval, mo= de); + case 15: + hi_addr =3D (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get()); + offset =3D get_bits (hi_addr, 16, 0); + m32c_cpu.h_pc_inc(2); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (offset); + m32c_cpu.raw_insn =3D (m32c_cpu.raw_insn << 16) + offset; + m32c_cpu.trace_str =3D int_to_string (offset) + "=3D" + int_to_stri= ng (newval); + return m32c_cpu.h_memset (offset, newval, mode); + } + } +=20 + #define BIT(n) ((unsigned long)(insn>>(15 - (n))) & 1) /* bit n of = instruction */ + #define BITS(s,l) ((unsigned long)(insn << (s + 16)) >> (32 - (l))) +=20 + enum execute_status {have_exit=3D1}; +=20 + execute_status + execute_insn () + { + QI qi_src; + QI qi_dest; + HI hi_src; + HI hi_dest; + UHI insn; + QI *qi_addr; + HI *hi_addr; +=20=20=20 + hi_addr =3D (HI*)(m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get()); + insn =3D get_bits (hi_addr, 16, 1); + m32c_cpu.h_pc_inc(2); + m32c_cpu.raw_insn =3D insn; +=20 + // op imm,dest + switch (BITS (0, 12)) + { + case 0x76F: + m32c_cpu.insn_str =3D "abs.b "; + qi_src =3D 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 =3D "abs.w "; + hi_src =3D 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 =3D "adc.b.g "; + qi_src =3D get_imm_src (BITS (12, 4), qi); + qi_dest =3D 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 =3D "adc.w.g "; + hi_src =3D get_imm_src (BITS (12, 4), hi); + hi_dest =3D 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 =3D "adcf.b "; + qi_src =3D 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 =3D "adcf.w "; + hi_src =3D 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 =3D "add.b.g "; + qi_src =3D get_imm_src (BITS (12, 4), qi); + qi_dest =3D 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 =3D "add.w.g "; + hi_src =3D get_imm_src (BITS (12, 4), hi); + hi_dest =3D 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 =3D "add.b.q "; + qi_src =3D (signed QI) BITS (12, 4); + m32c_cpu.insn_str =3D 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 =3D "and.b.g "; + qi_src =3D get_imm_src (BITS (12, 4), qi); + qi_dest =3D 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 =3D "and.w.g "; + hi_src =3D get_imm_src (BITS (12, 4), hi); + hi_dest =3D 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 =3D "cmp.b.g "; + qi_src =3D get_imm_src (BITS (12, 4), qi); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (qi_src); + qi_dest =3D 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) =3D=3D 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 =3D "cmp.w.g "; + hi_src =3D get_imm_src (BITS (12, 4), hi); + hi_dest =3D 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) =3D=3D 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 =3D "div.b "; + qi_src =3D get_src (BITS (12, 4), qi, src_op); + quotient =3D m32c_cpu.h_rget (0, hi) / qi_src; + remainder =3D 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 =3D m32c_cpu.trace_str + + m32c_cpu.h_gregname (0, qi) + "=3D" + int_to_string (quotient) + " " + + m32c_cpu.h_gregname (1, qi) + + "=3D" + int_to_string (remainder); + goto DONE_ONE_INSN; + } + case 0x77D: + { + HI quotient; + HI remainder; + m32c_cpu.insn_str =3D "div.w "; + hi_src =3D get_src (BITS (12, 4), hi, src_op); + quotient =3D m32c_cpu.h_rget (0, si) / hi_src; + remainder =3D 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 =3D m32c_cpu.trace_str + + m32c_cpu.h_gregname (0, hi) + "=3D" + + int_to_string (quotient) + " " + m32c_cpu.h_gregname (1, hi) + "=3D" + + int_to_string (remainder); + goto DONE_ONE_INSN; + } + case 0x76C: + { + QI quotient; + QI remainder; + m32c_cpu.insn_str =3D "divu.b "; + qi_src =3D get_src (BITS (12, 4), qi, src_op); + quotient =3D (UHI)m32c_cpu.h_rget (0, hi) / (UQI)qi_src; + remainder =3D (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 =3D m32c_cpu.trace_str + + m32c_cpu.h_gregname (0, qi) + "=3D" + + int_to_string (quotient) + " " + m32c_cpu.h_gregname (1, qi) + "=3D" + + int_to_string (remainder); + goto DONE_ONE_INSN; + } + case 0x77C: + { + HI quotient; + HI remainder; + m32c_cpu.insn_str =3D "divu.w "; + hi_src =3D get_src (BITS (12, 4), hi, src_op); + quotient =3D (USI)m32c_cpu.h_rget (0, si) / (UHI)hi_src; + remainder =3D (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 =3D m32c_cpu.trace_str + + m32c_cpu.h_gregname (0, hi) + "=3D" + + int_to_string (quotient) + " " + m32c_cpu.h_gregname (1, hi) + "=3D" + + int_to_string (remainder); + goto DONE_ONE_INSN; + } + case 0x74C: + m32c_cpu.insn_str =3D "mov.b "; + qi_src =3D 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 =3D "mov.w "; + hi_src =3D 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; + } +=20 + // op src,dest + switch (BITS (0, 8)) + { + case 0xB0: + m32c_cpu.insn_str =3D "adc.b.g "; + qi_src =3D get_src (BITS (8, 4), qi, src_op); + qi_dest =3D 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 =3D "adc.w.g "; + hi_src =3D get_src (BITS (8, 4), hi, src_op); + hi_dest =3D 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 =3D "add.b.g "; + qi_src =3D get_src (BITS (8, 4), qi, src_op); + qi_dest =3D 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 =3D "add.w.g "; + hi_src =3D get_src (BITS (8, 4), hi, src_op); + hi_dest =3D 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 =3D "add.b.q "; + qi_src =3D (signed QI) BITS (8, 4); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (qi_src) + = ","; + qi_dest =3D 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 =3D "add.w.q "; + hi_src =3D (signed HI) BITS (8, 4); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (hi_src) + = ","; + hi_dest =3D 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 =3D "and.b.g "; + qi_src =3D get_src (BITS (8, 4), qi, src_op); + qi_dest =3D 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 =3D "and.w.g "; + hi_src =3D get_src (BITS (8, 4), hi, src_op); + hi_dest =3D 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 =3D "cmp.b.g "; + qi_src =3D get_src (BITS (8, 4), qi, src_op); + qi_dest =3D 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) =3D=3D 0); + m32c_cpu.h_flag_s_set (qi_src < qi_dest); + goto DONE_ONE_INSN; + case 0xC1: + m32c_cpu.insn_str =3D "cmp.w.g "; + hi_src =3D get_src (BITS (8, 4), hi, src_op); + hi_dest =3D 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) =3D=3D 0); + m32c_cpu.h_flag_s_set (hi_src < hi_dest); + goto DONE_ONE_INSN; + case 0xD0: + m32c_cpu.insn_str =3D "cmp.b.q "; + qi_src =3D (signed QI) BITS (8, 4); + qi_dest =3D 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) =3D=3D 0); + m32c_cpu.h_flag_s_set (qi_src < qi_dest); + goto DONE_ONE_INSN; + case 0xD1: + m32c_cpu.insn_str =3D "cmp.w.q "; + hi_src =3D (signed HI) BITS (8, 4); + hi_dest =3D 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) =3D=3D 0); + m32c_cpu.h_flag_s_set (hi_src < hi_dest); + goto DONE_ONE_INSN; + case 0x72: + m32c_cpu.insn_str =3D "mov.b "; + qi_src =3D 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 =3D "mov.w "; + hi_src =3D 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 =3D "nop "; + m32c_cpu.h_pc_inc (1); + goto DONE_ONE_INSN; + case 0xEB: + return have_exit; + default: + goto DONE_ONE_INSN; + } +=20 + switch (BITS (0, 12)) + { + case 0x7CF2: + m32c_cpu.insn_str =3D "enter "; + qi_addr =3D m32c_cpu.h_qitext_get() + m32c_cpu.h_pc_get(); + qi_src =3D get_bits (qi_addr, 8, 0); + m32c_cpu.insn_str =3D m32c_cpu.insn_str + int_to_string (qi_src); + m32c_cpu.raw_insn =3D (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 =3D "fb=3D" + int_to_string (m32c_cpu.h_fb_get()= ) + " sp=3D" + + int_to_string (m32c_cpu.h_sp_get()); + m32c_cpu.h_pc_inc (1); + } +=20 + 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 =3D 0; + m32c_cpu.insn_str =3D ""; + m32c_cpu.trace_str =3D ""; + } + // 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 + } +=20 + const struct TextSection *section_table; +=20 + int + main (int argc, QI **argv) + { + int fdin; + QI *src; + struct stat statbuf; + USI entry; + int endian; + USI e_flags; + int text_end; +=20 + if (argc !=3D 2) + { + std::cout << "usage:" << argv[0] << "Executable-File" << std::endl; + exit (1); + } +=20=20 + /* open the input file */ + if ((fdin =3D open (argv[1], O_RDONLY)) < 0) + { + std::cout << "Cannot open" << argv[1] << std::endl; + exit (1); + } +=20 + /* find size of input file */ + if (fstat (fdin,&statbuf) < 0) + { + std::cout << "fstat error" << std::endl; + exit (1); + } +=20 + /* mmap the input file */ + if ((src =3D (QI*) mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin= , 0)) + =3D=3D (caddr_t) -1) + { + std::cout << "mmap error for input" << std::endl; + exit (1); + } +=20 +=20 + 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); + } +=20=20=20=20 + // 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 =3D m32c_cpu.h_pc_get() + textSectionEnd(); +=20 + for (int i =3D 0; m32c_cpu.h_pc_get() <=3D text_end; i++) + { + if (execute_insn () =3D=3D have_exit) + break; + } + } Index: sim/m32c/safe-fgets.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 + #include +=20 + #include "safe-fgets.h" +=20 + static char *line_buf =3D 0; + static int line_buf_size =3D 0; +=20 + #define LBUFINCR 100 +=20 + char * + safe_fgets(FILE *f) + { + char *line_ptr; +=20=20=20 + if (line_buf =3D=3D 0) + { + line_buf =3D (char *)malloc(LBUFINCR); + line_buf_size =3D LBUFINCR; + } +=20 + /* points to last byte */ + line_ptr =3D line_buf + line_buf_size - 1; +=20 + /* so we can see if fgets put a 0 there */ + *line_ptr =3D 1; + if (fgets(line_buf, line_buf_size, f) =3D=3D 0) + return 0; +=20 + /* we filled the buffer? */ + while (line_ptr[0] =3D=3D 0 && line_ptr[-1] !=3D '\n') + { + /* Make the buffer bigger and read more of the line */ + line_buf_size +=3D LBUFINCR; + line_buf =3D (char *) realloc (line_buf, line_buf_size); +=20 + /* points to last byte again */ + line_ptr =3D line_buf + line_buf_size - 1; + /* so we can see if fgets put a 0 there */ + *line_ptr =3D 1; +=20 + if (fgets(line_buf+line_buf_size-LBUFINCR-1, LBUFINCR+1, f) =3D=3D 0) + return 0; + } +=20 + return line_buf; + } Index: sim/m32c/safe-fgets.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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_ +=20 + char* safe_fgets(FILE *f); +=20 + #endif Index: sim/m32c/sample.S =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 +=20 + .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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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) +=20 + MEMORY { + RAM1 (w) : ORIGIN =3D 0xc800, LENGTH =3D 0x0200 + RAM2 (w) : ORIGIN =3D 0xca56, LENGTH =3D 0x1000 + ROM (w) : ORIGIN =3D 0x30000, LENGTH =3D 0x1000 + } +=20 + SECTIONS { + .data : { + *(.data*) + } > RAM1 + .text : { + *(.text*) + } > RAM2 + .fardata : { + *(.fardata*) + } > ROM + } Index: sim/m32c/sample2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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); +=20 + start() + { + foo(1,2,3,4); + exit(5); + } Index: sim/m32c/srcdest.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 + #include +=20 + #include "cpu.h" + #include "mem.h" +=20 + static int src_indirect =3D 0; + static int dest_indirect =3D 0; + static int src_addend =3D 0; + static int dest_addend =3D 0; +=20 + static int disp8() + { + int rv; + int tsave =3D trace; +=20 + if (trace =3D=3D 1) + trace =3D 0; + rv =3D mem_get_qi (get_reg (pc)); + regs.r_pc ++; + trace =3D tsave; + return rv; + } +=20 + static int disp16() + { + int rv; + int tsave =3D trace; +=20 + if (trace =3D=3D 1) + trace =3D 0; + rv =3D mem_get_hi (get_reg (pc)); + regs.r_pc +=3D 2; + trace =3D tsave; + return rv; + } +=20 + static int disp24() + { + int rv; + int tsave =3D trace; +=20 + if (trace =3D=3D 1) + trace =3D 0; + rv=3D mem_get_psi (get_reg (pc)); + regs.r_pc +=3D 3; + trace =3D tsave; + return rv; + } +=20 + static int disp20() + { + return disp24() & 0x000fffff; + } +=20 + const char * + bits (int v, int b) + { + static char buf[17]; + char *bp =3D buf+16; + *bp =3D 0; + while (b) + { + *--bp =3D (v & 1) ? '1' : '0'; + v >>=3D 1; + b--; + } + return bp; + } +=20 + static const char *the_bits =3D 0; +=20 + void + decode_indirect (int si, int di) + { + src_indirect =3D si; + dest_indirect =3D di; + if (trace && (si || di)) + printf("indirect: s:%d d:%d\n", si, di); + } +=20 + void + decode_index (int sa, int da) + { + src_addend =3D sa; + dest_addend =3D da; + if (trace && (sa || da)) + printf("index: s:%d d:%d\n", sa, da); + } +=20 + srcdest + decode_srcdest4 (int destcode, int bw) + { + srcdest sd; + sd.bytes =3D bw ? 2 : 1; + sd.mem =3D (destcode >=3D 6) ? 1 : 0; + static const char *dc_wnames[16] =3D {"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] =3D {"r0l", "r0h", "r1l", "r1h"};; +=20 + if (trace) + { + const char *n =3D dc_wnames[destcode]; + if (bw =3D=3D 0 && destcode <=3D 3) + n =3D dc_bnames[destcode]; + if (!the_bits) + the_bits =3D bits(destcode, 4); + printf("decode: %s (%d) : %s\n", the_bits, destcode, n); + the_bits =3D 0; + } +=20 + switch (destcode) + { + case 0x0: sd.u.reg =3D bw ? r0 : r0l; break; + case 0x1: sd.u.reg =3D bw ? r1 : r0h; break; + case 0x2: sd.u.reg =3D bw ? r2 : r1l; break; + case 0x3: sd.u.reg =3D bw ? r3 : r1h; break; + case 0x4: sd.u.reg =3D a0; break; + case 0x5: sd.u.reg =3D a1; break; + case 0x6: sd.u.addr =3D get_reg (a0); break; + case 0x7: sd.u.addr =3D get_reg (a1); break; + case 0x8: sd.u.addr =3D get_reg (a0) + disp8(); break; + case 0x9: sd.u.addr =3D get_reg (a1) + disp8(); break; + case 0xa: sd.u.addr =3D get_reg (sb) + disp8(); break; + case 0xb: sd.u.addr =3D get_reg (fb) + sign_ext (disp8(), 8); break; + case 0xc: sd.u.addr =3D get_reg (a0) + disp16(); break; + case 0xd: sd.u.addr =3D get_reg (a1) + disp16(); break; + case 0xe: sd.u.addr =3D get_reg (sb) + disp16(); break; + case 0xf: sd.u.addr =3D disp16(); break; + default: abort(); + } + if (sd.mem) + sd.u.addr &=3D addr_mask; + return sd; + } +=20 + srcdest + decode_jumpdest (int destcode, int w) + { + srcdest sd; + sd.bytes =3D w ? 2 : 3; + sd.mem =3D (destcode >=3D 6) ? 1 : 0; + static const char *dc_wnames[16] =3D {"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] =3D {"r0l", "r0h", "r1l", "r1h"}; +=20 + if (trace) + { + const char *n =3D dc_wnames[destcode]; + if (w =3D=3D 0 && destcode <=3D 3) + n =3D dc_anames[destcode]; + if (!the_bits) + the_bits =3D bits(destcode, 4); + printf("decode: %s : %s\n", the_bits, n); + the_bits =3D 0; + } +=20 + switch (destcode) + { + case 0x0: sd.u.reg =3D w ? r0 : r2r0; break; + case 0x1: sd.u.reg =3D w ? r1 : r2r0; break; + case 0x2: sd.u.reg =3D w ? r2 : r3r1; break; + case 0x3: sd.u.reg =3D w ? r3 : r3r1; break; + case 0x4: sd.u.reg =3D w ? a0 : a1a0; break; + case 0x5: sd.u.reg =3D w ? a1 : a1a0; break; + case 0x6: sd.u.addr =3D get_reg (a0); break; + case 0x7: sd.u.addr =3D get_reg (a1); break; + case 0x8: sd.u.addr =3D get_reg (a0) + disp8(); break; + case 0x9: sd.u.addr =3D get_reg (a1) + disp8(); break; + case 0xa: sd.u.addr =3D get_reg (sb) + disp8(); break; + case 0xb: sd.u.addr =3D get_reg (fb) + sign_ext (disp8(), 8); break; + case 0xc: sd.u.addr =3D get_reg (a0) + disp20(); break; + case 0xd: sd.u.addr =3D get_reg (a1) + disp20(); break; + case 0xe: sd.u.addr =3D get_reg (sb) + disp16(); break; + case 0xf: sd.u.addr =3D disp16(); break; + default: abort(); + } + if (sd.mem) + sd.u.addr &=3D addr_mask; + return sd; + } +=20 + srcdest + decode_dest3 (int destcode, int bw) + { + static char map[8] =3D { -1, -1, -1, 1, 0, 10, 11, 15 }; +=20 + the_bits =3D bits(destcode, 3); + return decode_srcdest4(map[destcode], bw); + } +=20 + srcdest + decode_src2 (int srccode, int bw, int d) + { + static char map[4] =3D { 0, 10, 11, 15 }; +=20 + the_bits =3D bits(srccode, 2); + return decode_srcdest4(srccode ? map[srccode] : 1-d, bw); + } +=20 + static struct { + reg_id b_regno; + reg_id w_regno; + int is_memory; + int disp_bytes; + char *name; + } modes23[] =3D { + { 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 */ + }; +=20 + static srcdest + decode_sd23 (int bbb, int bb, int bytes, int ind, int add) + { + srcdest sd; + int code =3D (bbb << 2) | bb; +=20 + if (code >=3D sizeof (modes23) / sizeof (modes23[0])) + abort(); +=20 + if (trace) + { + char *b1 =3D ""; + char *b2 =3D ""; + char ad[30]; + if (ind) + { + b1 =3D "["; + b2 =3D "]"; + } + if (add) + sprintf(ad, "%+d", add); + else + ad[0] =3D 0; + if (!the_bits) + the_bits =3D bits(code, 4); + printf("decode: %s (%d) : %s%s%s%s\n", the_bits, code, b1, modes23[= code].name, ad, b2); + the_bits =3D 0; + } +=20 + sd.bytes =3D bytes; + sd.mem =3D modes23[code].is_memory; + if (sd.mem) + { + if (modes23[code].w_regno =3D=3D mem) + sd.u.addr =3D 0; + else + sd.u.addr =3D get_reg (modes23[code].w_regno); + switch (modes23[code].disp_bytes) + { + case 1: + sd.u.addr +=3D disp8 (); + break; + case 2: + sd.u.addr +=3D disp16 (); + break; + case -1: + sd.u.addr +=3D sign_ext (disp8 (), 8); + break; + case -2: + sd.u.addr +=3D sign_ext (disp16 (), 16); + break; + case 3: + sd.u.addr +=3D disp24 (); + break; + default: + break; + } + if (add) + sd.u.addr +=3D add; + if (ind) + sd.u.addr =3D mem_get_si (sd.u.addr & membus_mask); + sd.u.addr &=3D membus_mask; + } + else + { + sd.u.reg =3D (bytes>1) ? modes23[code].w_regno : modes23[code].b_re= gno; + if (bytes =3D=3D 3 || bytes =3D=3D 4) + { + switch (sd.u.reg) + { + case r0: sd.u.reg =3D r2r0; break; + case r1: sd.u.reg =3D r3r1; break; + case r2: abort(); + case r3: abort(); + default: ; + } + } +=20=09=20=20 + } + return sd; + } +=20 + srcdest + decode_dest23 (int ddd, int dd, int bytes) + { + return decode_sd23 (ddd, dd, bytes, dest_indirect, dest_addend); + } +=20 + srcdest + decode_src23 (int sss, int ss, int bytes) + { + return decode_sd23 (sss, ss, bytes, src_indirect, src_addend); + } +=20 + srcdest + decode_dest2 (int dd, int bytes) + { + /* r0l/r0, abs16, dsp:8[SB], dsp:8[FB] */ + static char map[4] =3D { 0x12, 0x0f, 0x06, 0x07 }; +=20 + the_bits =3D bits(dd, 2); + return decode_sd23 (map[dd]>>2, map[dd]&3, bytes, dest_indirect, dest_a= ddend); + } +=20 + srcdest + decode_src3 (int sss, int bytes) + { + /* r0, r1, a0, a1, r2, r3, N/A, N/A */ + static char map[8] =3D { 0x12, 0x13, 0x02, 0x03, 0x10, 0x11, 0, 0 }; +=20 + the_bits =3D bits(sss, 3); + return decode_sd23 (map[sss]>>2, map[sss]&3, bytes, src_indirect, src_a= ddend); + } +=20 + srcdest + decode_dest1 (int destcode, int bw) + { + the_bits =3D bits(destcode, 1); + return decode_srcdest4(destcode, bw); + } +=20 + srcdest + decode_cr (int crcode) + { + static int regcode[] =3D { 0, intbl, intbh, flags, isp, sp, sb, fb }; + srcdest sd; + sd.mem =3D 0; + sd.bytes =3D 2; + sd.u.reg =3D regcode[crcode & 7]; + return sd; + } +=20 + srcdest + decode_cr_b (int crcode, int bank) + { + /* FIXME: intbl, intbh, isp */ + static int regcode[3][8] =3D { + { 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 =3D 0; + sd.bytes =3D bank ? 3 : 2; + sd.u.reg =3D regcode[bank][crcode & 7]; + return sd; + } +=20 + srcdest + widen_sd (srcdest sd) + { + sd.bytes *=3D 2; + if (!sd.mem) + switch (sd.u.reg) + { + case r0l: sd.u.reg =3D r0; break; + case r0: sd.u.reg =3D r2r0; break; + case r1l: sd.u.reg =3D r1; break; + case r1: sd.u.reg =3D r3r1; break; + case a0: + if (A16) + sd.u.reg =3D a1a0; + break; + default: break; + } + return sd; + } +=20 + srcdest + reg_sd (reg_id reg) + { + srcdest rv; + rv.bytes =3D reg_bytes[reg]; + rv.mem =3D 0; + rv.u.reg =3D reg; + return rv; + } +=20 + int + get_src (srcdest sd) + { + int v; + if (sd.mem) + { + switch (sd.bytes) + { + case 1: + v =3D mem_get_qi (sd.u.addr); + break; + case 2: + v =3D mem_get_hi (sd.u.addr); + break; + case 3: + v =3D mem_get_psi (sd.u.addr); + break; + case 4: + v =3D mem_get_si (sd.u.addr); + break; + default: + abort(); + } + } + else + { + v =3D get_reg (sd.u.reg); + switch (sd.bytes) + { + case 1: v &=3D 0xff; break; + case 2: v &=3D 0xffff; break; + case 3: v &=3D 0xffffff; break; + } + } + return v; + } +=20 + 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 &=3D 0xff; break; + case 2: v &=3D 0xffff; break; + case 3: v &=3D 0xffffff; break; + } + put_reg (sd.u.reg, v); + } + } +=20 + srcdest + decode_bit (int destcode) + { + srcdest sd; + int addr =3D 0; + static const char *dc_names[] =3D {"r0", "r1", "r2", "r3", + "a0", "a1", "[a0]", "[a1]", + "disp8[a0]", "disp8[a1]", "disp8[sb]", "disp8[fb]", + "disp16[a0]", "disp16[a1]", "disp16[sb]", "abs16"}; +=20=20=20=20=20 + if (trace) + { + const char *the_bits =3D bits(destcode, 4); + printf("decode: %s : %s\n", the_bits, dc_names[destcode]); + } +=20 + switch (destcode) + { + case 0: sd.u.reg =3D r0; break; + case 1: sd.u.reg =3D r1; break; + case 2: sd.u.reg =3D r2; break; + case 3: sd.u.reg =3D r3; break; + case 4: sd.u.reg =3D a0; break; + case 5: sd.u.reg =3D a1; break; + case 6: addr =3D get_reg (a0); break; + case 7: addr =3D get_reg (a1); break; + case 8: addr =3D get_reg (a0) + disp8 (); break; + case 9: addr =3D get_reg (a1) + disp8 (); break; + case 10: addr =3D get_reg (sb)*8 + disp8 (); break; + case 11: addr =3D get_reg (fb)*8 + sign_ext (disp8 (), 8); break; + case 12: addr =3D get_reg (a0) + disp16 (); break; + case 13: addr =3D get_reg (a1) + disp16 (); break; + case 14: addr =3D get_reg (sb) + disp16 (); break; + case 15: addr =3D disp16 (); break; + } +=20 + if (destcode < 6) + { + int d =3D disp8(); + sd.mem =3D 0; + sd.mask =3D 1 << (d & 0x0f); + } + else + { + addr &=3D addr_mask; + sd.mem =3D 1; + sd.mask =3D 1 << (addr & 7); + sd.u.addr =3D addr >> 3; + } + return sd; + } +=20 + srcdest + decode_bit11 (int op0) + { + srcdest sd; + sd.mask =3D 1 << (op0 & 7); + sd.mem =3D 1; + sd.u.addr =3D get_reg (sb) + disp8 (); + return sd; + } +=20 + int + get_bit (srcdest sd) + { + int b; + if (sd.mem) + b =3D mem_get_qi (sd.u.addr) & sd.mask; + else + b =3D get_reg (sd.u.reg) & sd.mask; + return b ? 1 : 0; + } +=20 + void + put_bit (srcdest sd, int val) + { + int b; + if (sd.mem) + b =3D mem_get_qi (sd.u.addr); + else + b =3D get_reg (sd.u.reg); + if (val) + b |=3D sd.mask; + else + b &=3D ~sd.mask; + if (sd.mem) + mem_put_qi (sd.u.addr, b); + else + put_reg (sd.u.reg, b); + } +=20 + int + get_bit2 (srcdest sd, int bit) + { + int b; + if (sd.mem) + b =3D mem_get_qi (sd.u.addr + (bit >> 3)) & (1 << (bit & 7)); + else + b =3D get_reg (sd.u.reg) & (1 << bit); + return b ? 1 : 0; + } +=20 + void + put_bit2 (srcdest sd, int bit, int val) + { + int b; + if (sd.mem) + b =3D mem_get_qi (sd.u.addr + (bit >> 3)); + else + b =3D get_reg (sd.u.reg); + if (val) + b |=3D (1 << (bit & 7)); + else + b &=3D ~(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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 + #include + #include + #include + #include +=20 + #include "gdb/callback.h" +=20 + #include "cpu.h" + #include "mem.h" + #include "syscalls.h" +=20 + #include "../../libgloss/syscall.h" +=20 + /* The current syscall callbacks we're using. */ + static struct host_callback_struct *callbacks; +=20 + void + set_callbacks (struct host_callback_struct *cb) + { + callbacks =3D cb; + } +=20 +=20 + /* A16 ABI: arg1 in r1l (QI) or r1 (HI) or stack + arg2 in r2 (HI) or stack + arg3..N on stack + padding: none +=20 + A24 ABI: arg1 in r0l (QI) or r0 (HI) or stack + arg2..N on stack + padding: qi->hi +=20 + return value in r0l (QI) r0 (HI) r2r0 (SI) + structs: pointer pushed on stack last +=20 + */ +=20 + int argp, stackp; +=20 + static int + arg(int bytes) + { + int rv =3D 0; + argp++; + if (A16) + { + switch (argp) + { + case 1: + if (bytes =3D=3D 1) + return get_reg (r1l); + if (bytes =3D=3D 2) + return get_reg (r1); + break; + case 2: + if (bytes =3D=3D 2) + return get_reg (r2); + break; + } + } + else + { + switch (argp) + { + case 1: + if (bytes =3D=3D 1) + return get_reg (r0l); + if (bytes =3D=3D 2) + return get_reg (r0); + break; + } + } + if (bytes =3D=3D 0) + bytes =3D 2; + switch (bytes) + { + case 1: + rv =3D mem_get_qi (get_reg (sp) + stackp); + if (A24) + stackp ++; + break; + case 2: + rv =3D mem_get_hi (get_reg (sp) + stackp); + break; + case 3: + rv =3D mem_get_psi (get_reg (sp) + stackp); + if (A24) + stackp ++; + break; + case 4: + rv =3D mem_get_si (get_reg (sp) + stackp); + break; + } + stackp +=3D bytes; + return rv; + } +=20 + static void + read_target (char *buffer, int address, int count, int asciiz) + { + char byte; + while (count > 0) + { + byte =3D mem_get_qi (address++); + *buffer++ =3D byte; + if (asciiz && (byte =3D=3D 0)) + return; + count --; + } + } +=20 + static void + write_target (char *buffer, int address, int count, int asciiz) + { + char byte; + while (count > 0) + { + byte =3D *buffer++; + mem_put_qi (address++, byte); + if (asciiz && (byte =3D=3D 0)) + return; + count --; + } + } +=20 + #define PTRSZ (A16 ? 2 : 3) +=20 + static char *callnames[] =3D { + "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" + }; +=20 + void + m32c_syscall (int id) + { + static char buf[256]; + int rv; +=20 + argp =3D 0; + stackp =3D A16 ? 3 : 4; + if (trace) + printf("\033[31m/* SYSCALL(%d) =3D %s */\033[0m\n", id, callnames[id]= ); + switch (id) + { + case SYS_exit: + { + int ec =3D arg(2); + if (verbose) + printf("[exit %d]\n", ec); + step_result =3D M32C_MAKE_EXITED (ec); + } + break; +=20 + case SYS_open: + { + int path =3D arg(PTRSZ); + int oflags =3D arg(2); + int cflags =3D arg(2); +=20 + read_target (buf, path, 256, 1); + if (trace) printf("open(\"%s\",0x%x,%#o) =3D ", buf, oflags, cflags); +=20 + if (callbacks) + /* The callback vector ignores CFLAGS. */ + rv =3D callbacks->open (callbacks, buf, oflags); + else + { + int h_oflags =3D 0; +=20 + if (oflags & 0x0001) h_oflags |=3D O_WRONLY; + if (oflags & 0x0002) h_oflags |=3D O_RDWR; + if (oflags & 0x0200) h_oflags |=3D O_CREAT; + if (oflags & 0x0008) h_oflags |=3D O_APPEND; + if (oflags & 0x0400) h_oflags |=3D O_TRUNC; + rv =3D open (buf, h_oflags, cflags); + } + if (trace) printf("%d\n", rv); + put_reg (r0, rv); + } + break; +=20 + case SYS_close: + { + int fd =3D arg(2); +=20 + if (callbacks) + rv =3D callbacks->close(callbacks, fd); + else if (fd > 2) + rv =3D close(fd); + else + rv =3D 0; + if (trace) printf("close(%d) =3D %d\n", fd, rv); + put_reg (r0, rv); + } + break; +=20 + case SYS_read: + { + int fd =3D arg(2); + int addr =3D arg(PTRSZ); + int count =3D arg(2); +=20 + if (count > sizeof(buf)) + count =3D sizeof(buf); + if (callbacks) + rv =3D callbacks->read (callbacks, fd, buf, count); + else + rv =3D read (fd, buf, count); + if (trace) printf("read(%d,%d) =3D %d\n", fd, count, rv); + if (rv > 0) + write_target (buf, addr, rv, 0); + put_reg (r0, rv); + } + break; +=20 + case SYS_write: + { + int fd =3D arg(2); + int addr =3D arg(PTRSZ); + int count =3D arg(2); +=20 + if (count > sizeof(buf)) + count =3D 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 =3D callbacks->write (callbacks, fd, buf, count); + else + rv =3D write (fd, buf, count); + if (trace) printf("write(%d,%d) =3D %d\n", fd, count, rv); + put_reg (r0, rv); + } + break; +=20 + case SYS_getpid: + put_reg (r0, 42); + break; +=20 + case SYS_gettimeofday: + { + int tvaddr =3D arg(PTRSZ); + struct timeval tv; +=20 + rv =3D 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; +=20 + case SYS_kill: + { + int pid =3D arg(2); + int sig =3D arg(2); + if (pid =3D=3D 42) + { + if (verbose) + printf("[signal %d]\n", sig); + step_result =3D M32C_MAKE_STOPPED (sig); + } + } + break; +=20 + case 11: + { + int heaptop_arg =3D arg(PTRSZ); + if (trace) printf("sbrk: heap top set to %x\n", heaptop_arg); + heaptop =3D heaptop_arg; + if (heapbottom =3D=3D 0) + heapbottom =3D heaptop_arg; + } + break; +=20 + } + } Index: sim/m32c/syscalls.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 + #include + #include + #include + #include + #include + #include +=20 + #include "bfd.h" + #include "dis-asm.h" + #include "m32c-desc.h" +=20 + #include "cpu.h" + #include "mem.h" + #include "load.h" +=20 + 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; + } +=20 + /* Filter out (in place) symbols that are useless for disassembly. + COUNT is the number of elements in SYMBOLS. + Return the number of useful symbols. */ +=20 + static long + remove_useless_symbols (asymbol **symbols, long count) + { + register asymbol **in_ptr =3D symbols, **out_ptr =3D symbols; +=20 + while (--count >=3D 0) + { + asymbol *sym =3D *in_ptr++; +=20 + if (strstr(sym->name, "gcc2_compiled")) + continue; + if (sym->name =3D=3D NULL || sym->name[0] =3D=3D '\0') + continue; + if (sym->flags & (BSF_DEBUGGING)) + continue; + if (bfd_is_und_section (sym->section) + || bfd_is_com_section (sym->section)) + continue; +=20 + *out_ptr++ =3D sym; + } + return out_ptr - symbols; + } +=20 + static int=20 + compare_symbols (const PTR ap, const PTR bp) + { + const asymbol *a =3D *(const asymbol **)ap; + const asymbol *b =3D *(const asymbol **)bp; +=20 + 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; + } +=20 + static char opbuf[1000]; +=20 + static int + op_printf(char *buf, char *fmt, ...) + { + int ret; + va_list ap; +=20 + va_start (ap, fmt); + ret =3D vsprintf (opbuf+strlen(opbuf), fmt, ap); + va_end (ap); + return ret; + } +=20 + static bfd *current_bfd; +=20 + void + sim_disasm_init(bfd *prog) + { + current_bfd =3D prog; + } +=20 + typedef struct Files { + struct Files *next; + char *filename; + int nlines; + char **lines; + char *data; + } Files; + Files *files =3D 0; +=20 + static char * + load_file_and_line (const char *filename, int lineno) + { + Files *f; + for (f=3Dfiles; f; f=3Df->next) + if (strcmp (f->filename, filename) =3D=3D 0) + break; + if (!f) + { + int i; + struct stat s; + const char *found_filename, *slash; +=20 + found_filename =3D filename; + while (1) + { + if (stat (found_filename, &s) =3D=3D 0) + break; + slash =3D strchr(found_filename, '/'); + if (!slash) + return ""; + found_filename =3D slash + 1; + } +=20 + f =3D (Files *)malloc(sizeof(Files)); + f->next =3D files; + files =3D f; + f->filename =3D strdup (filename); + f->data =3D (char *)malloc (s.st_size + 2); + FILE *file =3D fopen(found_filename, "rb"); + fread (f->data, 1, s.st_size, file); + f->data[s.st_size] =3D 0; + fclose(file); +=20 + f->nlines =3D 1; + for (i=3D0; idata[i] =3D=3D '\n') + f->nlines ++; + f->lines =3D (char **)malloc (f->nlines * sizeof(char *)); + f->lines[0] =3D f->data; + f->nlines =3D 1; + for (i=3D0; idata[i] =3D=3D '\n') + { + f->lines[f->nlines] =3D f->data+i+1; + while (*f->lines[f->nlines] =3D=3D ' ' + || *f->lines[f->nlines] =3D=3D '\t') + f->lines[f->nlines]++; + f->nlines++; + f->data[i] =3D 0; + } + } + if (lineno < 1 || lineno > f->nlines) + return ""; + return f->lines[lineno-1]; + } +=20 + void + sim_disasm_one() + { + static int initted =3D 0; + static asymbol **symtab =3D 0; + static int symcount =3D 0; + static int last_sym =3D -1; + static struct disassemble_info info; + int storage, sym, bestaddr; + int min, max, i; + static asection *code_section =3D 0; + static bfd_vma code_base =3D 0; + asection *s; + int save_trace =3D trace; +=20 + static const char *prev_filename =3D ""; + static int prev_lineno =3D 0; + const char *filename; + const char *functionname; + unsigned int lineno; +=20 + int mypc =3D get_reg (pc); +=20 + if (current_bfd =3D=3D 0) + return; +=20 + trace =3D 0; +=20 + if (!initted) + { + initted =3D 1; + memset(&info, 0, sizeof(info)); + INIT_DISASSEMBLE_INFO(info, stdout, op_printf); + info.read_memory_func =3D sim_dis_read; + info.arch =3D bfd_get_arch (current_bfd); + info.mach =3D bfd_get_mach (current_bfd); + if (info.mach =3D=3D 0) + { + info.arch =3D bfd_arch_m32c; + info.mach =3D default_machine; + } + disassemble_init_for_target (&info); +=20 + storage =3D bfd_get_symtab_upper_bound (current_bfd); + if (storage > 0) + { + symtab =3D (asymbol **) malloc (storage); + symcount =3D bfd_canonicalize_symtab (current_bfd, symtab); + symcount =3D remove_useless_symbols (symtab, symcount); + qsort (symtab, symcount, sizeof(asymbol *), compare_symbols); + } + for (s =3D current_bfd->sections; s; s =3D s->next)=20 + { + if (s->flags & SEC_CODE || code_section =3D=3D 0) + { + code_section =3D s; + code_base =3D bfd_section_lma (current_bfd, s); + break; + } + } + } +=20 + filename =3D functionname =3D 0; + lineno =3D 0; + if (bfd_find_nearest_line (current_bfd, code_section, symtab, mypc - co= de_base, + &filename, &functionname, &lineno)) + { + if (filename && functionname && lineno) + { + if (lineno !=3D prev_lineno || strcmp (prev_filename, filename)) + { + char *the_line =3D load_file_and_line (filename, lineno); + const char *slash =3D strrchr (filename, '/'); + if (!slash) slash =3D filename; else slash++; + printf("=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D\n"); + printf("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n", slash, = lineno, the_line); + } + prev_lineno =3D lineno; + prev_filename =3D filename; + } + } +=20 + { + min =3D -1; max =3D symcount; + while (min < max-1) { + bfd_vma sa; + sym =3D (min+max)/2; + sa =3D bfd_asymbol_value (symtab[sym]); + /*printf("checking %4d %08x %s\n", sym, sa, bfd_asymbol_name (symtab[sym= ]));*/ + if (sa > mypc) + max =3D sym; + else if (sa < mypc) + min =3D sym; + else + { + min =3D sym; + break; + } + } + if (min !=3D -1 && min !=3D last_sym) + { + bestaddr =3D bfd_asymbol_value (symtab[min]); + printf("\033[43;30m%s", bfd_asymbol_name (symtab[min])); + if (bestaddr !=3D mypc) + printf("+%d", mypc-bestaddr); + printf(":\t\t\t\033[0m\n"); + last_sym =3D min; + #if 0 + if (trace =3D=3D 1) + if (strcmp(bfd_asymbol_name (symtab[min]), "abort") =3D=3D 0 + || strcmp(bfd_asymbol_name (symtab[min]), "exit") =3D=3D 0) + trace =3D 0; + #endif + } + } +=20 + opbuf[0] =3D 0; + printf("\033[33m%06x: ", mypc); + max =3D print_insn_m32c(mypc, &info); + for (i=3D0; i