]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/tic80/interp.c
Add semantic tracing to the tic80
[thirdparty/binutils-gdb.git] / sim / tic80 / interp.c
index 304fe7336cc242ba953a278956521ed616c9bfcb..7e900eea24271baab94697a61bd7022f41872e64 100644 (file)
@@ -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);
     }
 }
+
+\f
+#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 */