1
2/*---------------------------------------------------------------*/
3/*--- begin                                        dispatch.c ---*/
4/*---------------------------------------------------------------*/
5
6#include "basictypes.h"
7
8
9/* --------------------------------------------------------- */
10/* TRANSLATION TABLE/CACHE                                   */
11/* --------------------------------------------------------- */
12
13static
14char* find_translation ( char* orig )
15{
16   int i;
17   for (i = 0; i < n_transtab_used; i++)
18      if (transtab[i].orig == orig)
19         return transtab[i].trans;
20   return NULL;
21}
22
23
24#define N_TT_ENTRIES 1000
25
26typedef
27   struct {
28      char* orig;
29      int   orig_size;
30      char* trans;
31      int   trans_size;
32   }
33   TTEntry;
34
35int n_transtab_used = 0;
36TTEntry transtab[N_TT_ENTRIES];
37
38
39/* Call here to add a translation to the trans cache.
40   Supplied translation is in mallocville.  add_translation should
41   copy it out as the caller will free it on return.  */
42
43/* EXPORTED */
44void add_translation ( char* orig, int orig_size, char* trans, int trans_size )
45{
46   int i;
47   assert(n_transtab_used < N_TT_ENTRIES);
48   transtab[n_transtab_used].orig       = orig;
49   transtab[n_transtab_used].orig_size  = orig_size;
50   transtab[n_transtab_used].trans_size = trans_size;
51
52   transtab[n_transtab_used].trans = malloc(trans_size);
53   assert(transtab[n_transtab_used].trans != NULL);
54   for (i = 0; i < trans_size; i++)
55      transtab[n_transtab_used].trans[i] = trans[i];
56
57#ifdef arm_TARGET_ARCH
58   arm_notify_new_code(transtab[n_transtab_used].trans, trans_size);
59#endif
60
61   n_transtab_used++;
62}
63
64/* Run the simulated machine for a while.  Returns when a new BB needs
65   to be translated, and returns its address.  Returns NULL when we
66   want to stop. */
67
68/* EXPORTED */
69char* run_machine ( void )
70{
71   char* nextpc_orig;
72   char* nextpc_trans;
73   while (1) {
74      nextpc_orig = (char*)(regs_arm[REG_PC]);
75      if (nextpc_orig == stop_at)
76         return NULL;
77      nextpc_trans = find_translation(nextpc_orig);
78      if (nextpc_trans == NULL)
79         return nextpc_orig;
80      run_translation(nextpc_trans, (char*) &regs_arm[0] );
81   }
82}
83
84
85/* HOW TO USE:
86
87   for a main fn :: void main ( void )
88
89   * load .o's, link, etc
90
91   * call initialise_machine with & main
92
93   * call run_machine repeatedly.  If it returns NULL, stop.  Else
94     make a translation of the returned address, pass it to
95     add_translation, and resume running by calling run_machine.
96
97*/
98