1 
2 /*---------------------------------------------------------------*/
3 /*--- begin                                        dispatch.c ---*/
4 /*---------------------------------------------------------------*/
5 
6 #include "basictypes.h"
7 
8 
9 /* --------------------------------------------------------- */
10 /* TRANSLATION TABLE/CACHE                                   */
11 /* --------------------------------------------------------- */
12 
13 static
find_translation(char * orig)14 char* 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 
26 typedef
27    struct {
28       char* orig;
29       int   orig_size;
30       char* trans;
31       int   trans_size;
32    }
33    TTEntry;
34 
35 int n_transtab_used = 0;
36 TTEntry 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 */
add_translation(char * orig,int orig_size,char * trans,int trans_size)44 void 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 */
run_machine(void)69 char* 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