blob: caab020e490b49896ae9e5a4b9f4801e902a4fac [file] [log] [blame]
/*---------------------------------------------------------------*/
/*--- ---*/
/*--- This file (dispatch.c) is ---*/
/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
/*--- ---*/
/*---------------------------------------------------------------*/
#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*) &regs_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.
*/