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*) ®s_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