97 lines
2.4 KiB
C
97 lines
2.4 KiB
C
|
|
/*---------------------------------------------------------------*/
|
|
/*--- begin dispatch.c ---*/
|
|
/*---------------------------------------------------------------*/
|
|
|
|
#include "basictypes.h"
|
|
|
|
|
|
/* --------------------------------------------------------- */
|
|
/* TRANSLATION TABLE/CACHE */
|
|
/* --------------------------------------------------------- */
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
#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];
|
|
|
|
|
|
/* Call here 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];
|
|
|
|
#ifdef arm_TARGET_ARCH
|
|
arm_notify_new_code(transtab[n_transtab_used].trans, trans_size);
|
|
#endif
|
|
|
|
n_transtab_used++;
|
|
}
|
|
|
|
/* Run the simulated machine for a while. Returns when a new BB needs
|
|
to be translated, and returns its address. Returns NULL when we
|
|
want to stop. */
|
|
|
|
/* EXPORTED */
|
|
char* run_machine ( void )
|
|
{
|
|
char* nextpc_orig;
|
|
char* nextpc_trans;
|
|
while (1) {
|
|
nextpc_orig = (char*)(regs_arm[REG_PC]);
|
|
if (nextpc_orig == stop_at)
|
|
return NULL;
|
|
nextpc_trans = find_translation(nextpc_orig);
|
|
if (nextpc_trans == NULL)
|
|
return nextpc_orig;
|
|
run_translation(nextpc_trans, (char*) ®s_arm[0] );
|
|
}
|
|
}
|
|
|
|
|
|
/* HOW TO USE:
|
|
|
|
for a main fn :: void main ( void )
|
|
|
|
* load .o's, link, etc
|
|
|
|
* call initialise_machine with & main
|
|
|
|
* call run_machine repeatedly. If it returns NULL, stop. Else
|
|
make a translation of the returned address, pass it to
|
|
add_translation, and resume running by calling run_machine.
|
|
|
|
*/
|