diff options
Diffstat (limited to 'sim/tic80/interp.c')
-rw-r--r-- | sim/tic80/interp.c | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/sim/tic80/interp.c b/sim/tic80/interp.c index 304fe73..7e900ee 100644 --- a/sim/tic80/interp.c +++ b/sim/tic80/interp.c @@ -24,6 +24,7 @@ #include "sim-main.h" #include "idecode.h" +#include "itable.h" #include <signal.h> @@ -128,3 +129,211 @@ engine_run_until_stop (SIM_DESC sd, engine_halt (sd, cpu, cia, sim_stopped, SIGINT); } } + + +#if defined(WITH_TRACE) +/* Tracing support routines */ + +static char tic80_trace_buffer[1024]; +static int tic80_size_name; + +#define SIZE_HEX 8 +#define SIZE_DECIMAL 12 + +/* Initialize tracing by calculating the maximum name size */ +static void +tic80_init_trace (void) +{ + int i; + int len, max_len = 0; + + for (i = 0; i < (int)nr_itable_entries; i++) { + len = strlen (itable[i].name); + if (len > max_len) + max_len = len; + } + + tic80_size_name = max_len + sizeof(":m") - 1 + sizeof (":s") - 1; +} + +/* Trace the result of an ALU operation with 2 integer inputs and an integer output */ +char * +tic80_trace_alu3 (int indx, + unsigned32 result, + unsigned32 input1, + unsigned32 input2) +{ + char buf1[SIZE_DECIMAL+10], buf2[SIZE_DECIMAL+10], bufr[SIZE_DECIMAL+10]; + + if (!tic80_size_name) + tic80_init_trace (); + + sprintf (bufr, "(%ld)", (long) (signed32) result); + sprintf (buf1, "(%ld)", (long) (signed32) input1); + sprintf (buf2, "(%ld)", (long) (signed32) input2); + + sprintf (tic80_trace_buffer, "%-*s 0x%.*lx %-*s 0x%.*lx %-*s => 0x%.*lx %-*s", + tic80_size_name, itable[indx].name, + SIZE_HEX, input1, SIZE_DECIMAL, buf1, + SIZE_HEX, input2, SIZE_DECIMAL, buf2, + SIZE_HEX, result, SIZE_DECIMAL, bufr); + + return tic80_trace_buffer; +} + +/* Trace the result of an ALU operation with 1 integer input and an integer output */ +char * +tic80_trace_alu2 (int indx, + unsigned32 result, + unsigned32 input) +{ + char bufi[SIZE_DECIMAL+10], bufr[SIZE_DECIMAL+10]; + + if (!tic80_size_name) + tic80_init_trace (); + + sprintf (bufr, "(%ld)", (long) (signed32) result); + sprintf (bufi, "(%ld)", (long) (signed32) input); + + sprintf (tic80_trace_buffer, "%-*s 0x%.*lx %-*s %*s => 0x%.*lx %-*s", + tic80_size_name, itable[indx].name, + SIZE_HEX, input, SIZE_DECIMAL, bufi, + SIZE_HEX + SIZE_DECIMAL + 3, "", + SIZE_HEX, result, SIZE_DECIMAL, bufr); + + return tic80_trace_buffer; +} + +/* Trace the result of a NOP operation */ +char * +tic80_trace_nop (int indx) +{ + if (!tic80_size_name) + tic80_init_trace (); + + sprintf (tic80_trace_buffer, "%s:", itable[indx].name); + return tic80_trace_buffer; +} + +/* Trace the result of a data sink with one input */ +char * +tic80_trace_sink1 (int indx, unsigned32 input) +{ + char buf[SIZE_DECIMAL+10]; + + if (!tic80_size_name) + tic80_init_trace (); + + sprintf (buf, "(%ld)", (long) (signed32) input); + sprintf (tic80_trace_buffer, "%-*s: 0x%.*lx %-*s", + tic80_size_name, itable[indx].name, + SIZE_HEX, input, SIZE_DECIMAL, buf); + + return tic80_trace_buffer; +} + +/* Trace the result of a data sink with two inputs */ +char * +tic80_trace_sink2 (int indx, unsigned32 input1, unsigned32 input2) +{ + char buf1[SIZE_DECIMAL+10], buf2[SIZE_DECIMAL+10]; + + if (!tic80_size_name) + tic80_init_trace (); + + sprintf (buf1, "(%ld)", (long) (signed32) input1); + sprintf (buf2, "(%ld)", (long) (signed32) input2); + sprintf (tic80_trace_buffer, "%-*s: 0x%.*lx %-*s 0x%.*lx %-*s", + tic80_size_name, itable[indx].name, + SIZE_HEX, input1, SIZE_DECIMAL, buf1, + SIZE_HEX, input2, SIZE_DECIMAL, buf2); + + return tic80_trace_buffer; +} + +/* Trace the result of a conditional branch operation */ +char * +tic80_trace_cond_br (int indx, + int jump_p, + unsigned32 cond, + unsigned32 target) +{ + char buf[SIZE_DECIMAL+10]; + + if (!tic80_size_name) + tic80_init_trace (); + + sprintf (buf, "(%ld)", (long) (signed32) cond); + + if (jump_p) + sprintf (tic80_trace_buffer, + "%-*s 0x%.*lx %*s 0x%.*lx %-*s => 0x%.*lx", + tic80_size_name, itable[indx].name, + SIZE_HEX, target, SIZE_DECIMAL, "", + SIZE_HEX, cond, SIZE_DECIMAL, buf, + SIZE_HEX, target); + else + sprintf (tic80_trace_buffer, + "%-*s 0x%.*lx %*s 0x%.*lx %-*s => [fallthrough]", + tic80_size_name, itable[indx].name, + SIZE_HEX, target, SIZE_DECIMAL, "", + SIZE_HEX, cond, SIZE_DECIMAL, buf); + + return tic80_trace_buffer; +} + +/* Trace the result of a unconditional branch operation */ +char * +tic80_trace_ucond_br (int indx, + unsigned32 target) +{ + if (!tic80_size_name) + tic80_init_trace (); + + sprintf (tic80_trace_buffer, + "%-*s 0x%.*lx %*s => 0x%.*lx", + tic80_size_name, itable[indx].name, + SIZE_HEX, target, (SIZE_DECIMAL*2) + SIZE_HEX + 4, "", + SIZE_HEX, target); + + return tic80_trace_buffer; +} + +/* Trace the result of a load or store operation with 2 integer addresses + and an integer output or input */ +char * +tic80_trace_ldst (int indx, + int st_p, + int m_p, + int s_p, + unsigned32 value, + unsigned32 input1, + unsigned32 input2) +{ + char buf1[SIZE_DECIMAL+10], buf2[SIZE_DECIMAL+10], bufr[SIZE_DECIMAL+10]; + char name[40]; + + if (!tic80_size_name) + tic80_init_trace (); + + strcpy (name, itable[indx].name); + if (m_p) + strcat (name, ":m"); + + if (s_p) + strcat (name, ":s"); + + sprintf (bufr, "(%ld)", (long) (signed32) value); + sprintf (buf1, "(%ld)", (long) (signed32) input1); + sprintf (buf2, "(%ld)", (long) (signed32) input2); + + sprintf (tic80_trace_buffer, "%-*s 0x%.*lx %-*s 0x%.*lx %-*s %s 0x%.*lx %-*s", + tic80_size_name, name, + SIZE_HEX, input1, SIZE_DECIMAL, buf1, + SIZE_HEX, input2, SIZE_DECIMAL, buf2, + (!st_p) ? "=>" : "<=", + SIZE_HEX, value, SIZE_DECIMAL, bufr); + + return tic80_trace_buffer; +} +#endif /* WITH_TRACE */ |