aboutsummaryrefslogtreecommitdiff
path: root/sim/tic80/interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/tic80/interp.c')
-rw-r--r--sim/tic80/interp.c209
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 */