]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Rudimentary support for translation table, run-time despatcher, etc.
authorJulian Seward <jseward@acm.org>
Sun, 4 Apr 2004 21:02:11 +0000 (21:02 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 4 Apr 2004 21:02:11 +0000 (21:02 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@10

VEX/runner.c [new file with mode: 0644]

diff --git a/VEX/runner.c b/VEX/runner.c
new file mode 100644 (file)
index 0000000..06d144d
--- /dev/null
@@ -0,0 +1,119 @@
+
+#include <stdlib.h>
+#include <malloc.h>
+#include <assert.h>
+
+/* --------------------------------------------------------- */
+/* TRANSLATION TABLE/CACHE                                   */
+/* --------------------------------------------------------- */
+
+
+#define N_TT_ENTRIES 1000
+
+typedef
+   struct {
+      char* orig;
+      int   orig_size;
+      char* trans;
+      int   trans_size;
+   }
+   TTEntry;
+
+int n_transtab_used = 0;
+TTEntry transtab[N_TT_ENTRIES];
+
+
+/* Called by Haskell to add a translation to the trans cache.
+   Supplied translation is in mallocville.  add_translation should
+   copy it out as the caller will free it on return.  */
+
+/* EXPORTED */
+void add_translation ( char* orig, int orig_size, char* trans, int trans_size )
+{
+   int i;
+   assert(n_transtab_used < N_TT_ENTRIES);
+   transtab[n_transtab_used].orig       = orig;
+   transtab[n_transtab_used].orig_size  = orig_size;
+   transtab[n_transtab_used].trans_size = trans_size;
+
+   transtab[n_transtab_used].trans = malloc(trans_size);
+   assert(transtab[n_transtab_used].trans != NULL);
+   for (i = 0; i < trans_size; i++)
+      transtab[n_transtab_used].trans[i] = trans[i];
+
+   n_transtab_used++;
+}
+
+static
+char* find_translation ( char* orig )
+{
+   int i;
+   for (i = 0; i < n_transtab_used; i++)
+      if (transtab[i].orig == orig)
+         return transtab[i].trans;
+   return NULL;
+}
+
+/* --------------------------------------------------------- */
+/* SIMULATED STATE                                           */
+/* --------------------------------------------------------- */
+
+typedef unsigned int Word;
+
+/* ARM state */
+/* r0 .. r15, flags */
+Word regs_arm[16+1];
+
+#define REG_PC 15
+#define REG_SP 14
+
+Word* sim_stack;
+
+//---------------------------------------------
+
+/* Calling convention: enter the translation with r0 pointing at
+   regs_arm.  Translation may trash r1 .. r12 inclusive. */
+
+static
+void run_translation ( char* trans )
+{
+  /* r0 holds trans */
+  __asm __volatile
+     ("stmfd   sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13}\n\t"
+      "mov     r12, %0\n\t"
+      "mov     r0, %1\n\t"
+      "bl      r12\n\t"
+      "ldmea   sp!, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13}\n\t"
+      :
+      : "ir" (trans), "ir" (&regs_arm[0]) );
+}
+
+
+
+/* Called by Haskell to initialise the simulated machine, and tell it
+   its starting pc. */
+
+/* EXPORTED */
+void initialise_machine ( char* first_pc )
+{
+   n_transtab_used = 0;
+   regs_arm[REG_PC] = (Word)first_pc;
+   sim_stack = malloc(10000 * sizeof(Word));
+   regs_arm[REG_SP] = (Word)(&sim_stack[9999]);
+}
+
+/* Run the simulated machine for a while.  Returns when a new BB needs
+   to be translated, and returns its address. */
+
+/* EXPORTED */
+char* run_machine ( void )
+{
+   char* trans;
+   while (1) {
+      trans = find_translation((char*)(regs_arm[15]));
+      if (trans == NULL) return (char*)(regs_arm[15]);
+      run_translation(trans);
+   }
+}
+
+