Hi, A client of ours, for whom we're developing a SID port, requested that SID's semantic trace show the actual value stored, accounting for read-only fields and other side effects, rather than showing the value which was attempted to be stored. For example, if a 32 bit register has the value 0x12345678 and is readonly in the 16 most significant bits, then storing the value zero actually results in 0x12340000 being stored. SID currently shows that the register has been set to zero. The most obvious idea I considered was to have the trace code re-read the stored value; This has problems with potential side effects of doing the read (caching statistics, control registers with side effects on read, etc.). I eventually came up with the notion that the write/set methods of SID's busses, control registers, memory access methods and hardware write handers could return the actual value written. Current code which does not make use of this can remain unchanged and simply ignore the return value. This allows the tracing code generated by CGEN for sid in the sem.cxx file to work with only a slight modification: For example, these extracts from xstormy16-sem.cxx. ----------------------- Index: sid/component/cgen-cpu/xstormy16/xstormy16-sem.cxx =================================================================== RCS file: /cvs/src/src/sid/component/cgen-cpu/xstormy16/xstormy16-sem.cxx,v retrieving revision 1.7 diff -c -p -r1.7 xstormy16-sem.cxx *** sid/component/cgen-cpu/xstormy16/xstormy16-sem.cxx 5 Jul 2003 17:07:21 -0000 1.7 --- sid/component/cgen-cpu/xstormy16/xstormy16-sem.cxx 17 Mar 2004 20:48:59 -0000 [ ... ] *************** if (FLD (f_op2m)) { *** 59,73 **** tmp_nvalue = FLD (f_imm16); { SI opval = ORSI (ANDSI (current_cpu->h_gr_get (((UINT) 14)), 65436), ORBI (ORBI (EQHI (ANDHI (tmp_nvalue, 255), 0), SLLHI (EQHI (tmp_nvalue, 0), 1)), ORHI (SLLHI (current_cpu->parity (tmp_nvalue), 5), SLLHI (LTQI (SRLHI (tmp_nvalue, MULSI (FLD (f_op2m), 8)), 0), 6)))); ! current_cpu->h_gr_set (((UINT) 14), opval); if (UNLIKELY(current_cpu->trace_result_p)) ! current_cpu->trace_stream << "gr" << '[' << ((UINT) 14) << ']' << ":=0x" << hex << opval << dec << " "; } { HI opval = tmp_nvalue; ! current_cpu->SETMEMHI (pc, ANDSI (FLD (f_lmem8), 65534), opval); if (UNLIKELY(current_cpu->trace_result_p)) ! current_cpu->trace_stream << "memory" << '[' << "0x" << hex << (UDI) ANDSI (FLD (f_lmem8), 65534) << dec << ']' << ":=0x" << hex << opval << dec << " "; } } } else { --- 59,73 ---- tmp_nvalue = FLD (f_imm16); { SI opval = ORSI (ANDSI (current_cpu->h_gr_get (((UINT) 14)), 65436), ORBI (ORBI (EQHI (ANDHI (tmp_nvalue, 255), 0), SLLHI (EQHI (tmp_nvalue, 0), 1)), ORHI (SLLHI (current_cpu->parity (tmp_nvalue), 5), SLLHI (LTQI (SRLHI (tmp_nvalue, MULSI (FLD (f_op2m), 8)), 0), 6)))); ! SI wval = current_cpu->h_gr_set (((UINT) 14), opval); if (UNLIKELY(current_cpu->trace_result_p)) ! current_cpu->trace_stream << "gr" << '[' << ((UINT) 14) << ']' << ":=0x" << hex << wval << dec << " "; } { HI opval = tmp_nvalue; ! HI wval = current_cpu->SETMEMHI (pc, ANDSI (FLD (f_lmem8), 65534), opval); if (UNLIKELY(current_cpu->trace_result_p)) ! current_cpu->trace_stream << "memory" << '[' << "0x" << hex << (UDI) ANDSI (FLD (f_lmem8), 65534) << dec << ']' << ":=0x" << hex << wval << dec << " "; } } } else { [ ... ] *************** xstormy16_sem_bccgrgr (xstormy16_cpu* cu *** 3803,3811 **** if (tmp_tmp) { { USI opval = FLD (f_rel12); ! current_cpu->branch (opval, npc, status); if (UNLIKELY(current_cpu->trace_result_p)) ! current_cpu->trace_stream << "pc" << ":=0x" << hex << opval << dec << " "; } } } --- 3803,3811 ---- if (tmp_tmp) { { USI opval = FLD (f_rel12); ! USI wval = current_cpu->branch (opval, npc, status); if (UNLIKELY(current_cpu->trace_result_p)) ! current_cpu->trace_stream << "pc" << ":=0x" << hex << wval << dec << " "; } } } ----------------------------------------------------- The only complication I ran into was that the write methods of the various busses already return a status. I decided that for bus writes, an additional pointer argument could be added which defaults to NULL (for existing callers not using the written value). This applies to all bus 'write' methods as well as callback bus write handlers and callback control register 'set' handlers. Control register 'set' methods can simply return the value which was written. Though simple in concept, these changes have proved quite pervasive. I've attached the complete patch for SID and for CGEN along with the sample generated code (above) and changes needed to the xstormy16_cpu. If this patch is approved, I will update the other SID ports as necessary before committing. Of course opinions and ideas are welcome. For example, should this be the way --trace-sem works from now on or should it be a CGEN option? I have tested this against 'make check-sid' for xstormy16 as well as against the entire toolchain testsuite for the port we're developing. Dave