Index: cgen/cpu/xstormy16.cpu =================================================================== RCS file: /cvs/src/src/cgen/cpu/xstormy16.cpu,v retrieving revision 1.12 diff -c -p -r1.12 xstormy16.cpu *** cgen/cpu/xstormy16.cpu 22 Jul 2004 01:49:27 -0000 1.12 --- cgen/cpu/xstormy16.cpu 15 Sep 2006 20:27:47 -0000 *************** *** 1,5 **** ; xstormy16 CPU core description. -*- Scheme -*- ! ; Copyright (C) 2001, 2002, 2003 Red Hat, Inc. ; This file is part of CGEN. ; See file COPYING.CGEN for details. --- 1,5 ---- ; xstormy16 CPU core description. -*- Scheme -*- ! ; Copyright (C) 2001, 2002, 2003, 2006 Red Hat, Inc. ; This file is part of CGEN. ; See file COPYING.CGEN for details. *************** *** 68,74 **** ; Hardware elements. ! (dsh h-pc "program counter" (PC) (pc)) (define-keyword (name gr-names) --- 68,80 ---- ; Hardware elements. ! (define-hardware ! (name h-pc) ! (comment "program counter") ! (attrs PC) ! (type pc) ! (set (newval) (c-call "h_pc_set_handler" newval)) ! ) (define-keyword (name gr-names) *************** *** 92,98 **** (type register WI (16)) (indices extern-keyword gr-names) (get (index) (and #xFFFF (raw-reg h-gr index))) ! (set (index newval) (set (raw-reg h-gr index) (and #xFFFF newval))) ) (define-hardware --- 98,104 ---- (type register WI (16)) (indices extern-keyword gr-names) (get (index) (and #xFFFF (raw-reg h-gr index))) ! (set (index newval) (c-call "h_gr_set_handler" index newval)) ) (define-hardware Index: sid/component/cgen-cpu/xstormy16/xstormy16.cxx =================================================================== RCS file: /cvs/src/src/sid/component/cgen-cpu/xstormy16/xstormy16.cxx,v retrieving revision 1.3 diff -c -p -r1.3 xstormy16.cxx *** sid/component/cgen-cpu/xstormy16/xstormy16.cxx 18 Feb 2003 22:57:29 -0000 1.3 --- sid/component/cgen-cpu/xstormy16/xstormy16.cxx 15 Sep 2006 20:27:52 -0000 *************** *** 1,7 **** // xstormy16.cxx - Implementations of hand-written functions for the Xstormy16 // simulator. -*- C++ -*- ! // Copyright (C) 2000 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. --- 1,7 ---- // xstormy16.cxx - Implementations of hand-written functions for the Xstormy16 // simulator. -*- C++ -*- ! // Copyright (C) 2000, 2006 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. *************** xstormy16_cpu::parity (int reg) *** 363,365 **** --- 363,507 ---- tmp ^= tmp >> 1; return tmp & 1; } + + // Called before execution of an insn. Perform any tasks associated with + // logging changes in the state of this cpu during execution of an insn. + void + xstormy16_cpu_cgen::init_change_logging () + { + // Call up to the base class. + cgen_bi_endian_cpu::init_change_logging (); + + // We will be tracking changes to the pc and to the gr registers. + gr_changed = 0; + pc_changed = PC_UNCHANGED; + } + + // Called after execution of an insn. Log the changes which occurred during + // execution of the insn. + void + xstormy16_cpu_cgen::finish_change_logging () + { + // Call up to the base class. + cgen_bi_endian_cpu::finish_change_logging (); + + // The largest possible record would contain: + // 1 byte representing the type of pc change + // A 16 bit mask indicating which gr registers changed + // Possibly the old pc value + // Old gr register values (if any) + char buffer[1 + 2 + sizeof (old_h_pc) + sizeof (old_h_gr)]; + + // Record the nature of any pc or gr changes. + *(sid::host_int_1 *)(buffer + 0) = pc_changed; + *(sid::host_int_2 *)(buffer + 1) = gr_changed; + + // If the pc change was too large to represent in the byte written above, then + // record the old pc value. + unsigned bufix = 3; + if (pc_changed == PC_RESET) + { + *(USI *)(buffer + bufix) = old_h_pc; + bufix += sizeof (old_h_pc); + } + + // Record the old values of any gr registers that changed. + sid::host_int_2 mask = 1; + for (int i = 0; i < 16; ++i) + { + if ((gr_changed & mask) != 0) + { + *(SI *)(buffer + bufix) = old_h_gr[i]; + bufix += sizeof (old_h_gr[i]); + // std::cout << ' ' << std::hex << old_h_gr[i] << std::dec; + } + mask <<= 1; + } + + // Save the change log record we have just created. + log_change (buffer, bufix); + } + + // Keep track of any changes to the pc. + void + xstormy16_cpu_cgen::log_pc_change (USI new_pc) + { + // If this is the first change, then save the original pc value. + if (LIKELY (pc_changed == PC_UNCHANGED)) + old_h_pc = this->hardware.h_pc; + + // Most of the time, pc changes are small enough to represented by one byte. + // Save these changes in 'pc_changed'. + // + // The value of PC_UNCHANGED is zero and so this condition will be represented + // with no special handling. + // + // The special value PC_RESET is an odd number and cannot occur under normal + // circumstances. It indicates a larger pc change. + SI diff = new_pc - old_h_pc; + if (LIKELY (-128 <= diff && diff <= 127)) + pc_changed = diff; + else + pc_changed = PC_RESET; + } + + // Keep track of any changes to gr registers. It is only necessary to + // save the original value of a register the first time it is changed. + void + xstormy16_cpu_cgen::log_gr_change (UINT regno, SI newval) + { + if (! (gr_changed & (1 << regno))) + { + gr_changed |= 1 << regno; + old_h_gr[regno] = this->hardware.h_gr[regno]; + } + } + + // Given a change log record, restore the state that it represents. + void + xstormy16_cpu_cgen::restore_change (const char *data, sid::host_int_4 length) + { + // The first byte indicates the nature of any change to the pc. + assert (length >= 1); + sid::signed_host_int_1 pc_changed = *(sid::host_int_1 *)data; + ++data; + --length; + + // The second two bytes are a bit mask indicating changes to gr registers. + assert (length >= 2); + sid::host_int_2 gr_changed = *(sid::host_int_2 *)data; + data += 2; + length -= 2; + + // Restore the pc. + if (UNLIKELY (pc_changed == PC_RESET)) + { + // For large changes to the pc, the previous pc value is recorded in the + // change log record. + this->hardware.h_pc = *(USI *)data; + data += sizeof (USI); + length -= sizeof (USI); + } + else + { + // Smaller changes to the pc are represented by a one byte delta. + this->hardware.h_pc -= pc_changed; + } + + // Restore any gr registers which changed. + sid::host_int_2 mask = 1; + for (int i = 0; i < 16; ++i) + { + if ((gr_changed & mask) != 0) + { + assert (length >= sizeof (SI)); + this->hardware.h_gr[i] = *(SI *)data; + data += sizeof (SI); + length -= sizeof (SI); + } + mask <<= 1; + } + + // The entire record must be consumed. + assert (length == 0); + } Index: sid/component/cgen-cpu/xstormy16/xstormy16.h =================================================================== RCS file: /cvs/src/src/sid/component/cgen-cpu/xstormy16/xstormy16.h,v retrieving revision 1.3 diff -c -p -r1.3 xstormy16.h *** sid/component/cgen-cpu/xstormy16/xstormy16.h 26 Jun 2006 21:06:41 -0000 1.3 --- sid/component/cgen-cpu/xstormy16/xstormy16.h 15 Sep 2006 20:27:52 -0000 *************** *** 1,6 **** // xstormy16.h - Hand-written code for the Sanyo Xstormy16 CPU. -*- C++ -*- ! // Copyright (C) 1999, 2000 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. --- 1,6 ---- // xstormy16.h - Hand-written code for the Sanyo Xstormy16 CPU. -*- C++ -*- ! // Copyright (C) 1999, 2000, 2006 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. *************** *** 11,32 **** namespace xstormy16 { ! class xstormy16_cpu_cgen { // Include cgen generated elements. #include "xstormy16-cpu.h" public: inline void cgen_rtx_error(const char* msg) const { cerr << "xstormy16-cpu rtx error: " << msg << endl; } protected: USI syscall_trap_num; }; ! class xstormy16_cpu: public xstormy16_cpu_cgen, public cgen_bi_endian_cpu { private: scache_engine engine; --- 11,72 ---- namespace xstormy16 { ! class xstormy16_cpu_cgen: public cgen_bi_endian_cpu { // Include cgen generated elements. #include "xstormy16-cpu.h" public: + xstormy16_cpu_cgen () {} + ~xstormy16_cpu_cgen () throw() { }; + + protected: + // Log any changes to the pc, if we're reversible. + void h_pc_set_handler (USI newval) + { + if (UNLIKELY (this->reversible_p)) + log_pc_change (newval); + this->hardware.h_pc = newval; + } + + // Log any changes to the gr registers, if we're reversible. + void h_gr_set_handler (UINT regno, SI newval) + { + if (UNLIKELY (this->reversible_p)) + log_gr_change (regno, newval); + this->hardware.h_gr[regno] = (0xffff & newval); + } + + // Stateful (reversible) component implementation methods. + virtual void init_change_logging (); + virtual void finish_change_logging (); + + void log_pc_change (USI new_pc); + void log_gr_change (UINT regno, SI newval); + + virtual void restore_change (const char *data, sid::host_int_4 length); + + protected: inline void cgen_rtx_error(const char* msg) const { cerr << "xstormy16-cpu rtx error: " << msg << endl; } + protected: USI syscall_trap_num; + // The values of these constants are significant and must not be changed. + static const sid::signed_host_int_1 PC_UNCHANGED = 0x00; + static const sid::signed_host_int_1 PC_RESET = 0x01; + + // State for change logging. + sid::host_int_2 gr_changed; + sid::signed_host_int_1 pc_changed; + SI old_h_gr[16]; + USI old_h_pc; }; ! class xstormy16_cpu: public xstormy16_cpu_cgen { private: scache_engine engine;